8

I am making plugin for Cordova and at the moment I am trying to make it support Windows platform. I have a DLL written in C# and I want to use functionalities from there in my plugin. In order to do that, I made Windows Runtime Component project which is "wrapper" around C# DLL and from there I expose methods to Java Script in Cordova and I can successfully call them. So, the communication between

App <-> Plugin <-> WinRT <-> C# DLL

works just fine.

At some point (in one of the methods in C# DLL) I am trying to do following:

Task.Factory.StartNew(() => ProcessQueue(), TaskCreationOptions.LongRunning);

Once code execution gets to this part I concluded that app just silently skips this part and ProcessQueue() method never starts to get executed in background task. First I thought that problem might be with the way I am starting this task in C#, so I tried several replacements for starting new background task - no luck.

Then I thought that I might make a call to plugin in Java Script from background thread (I am no Cordova / Java Script expert as you can see from this assumption), but quickly realized that it's not gonna happen. I discovered that calls made to native code as part of Cordova plugins are executed not in main UI thread, but rather in some other thread, but still, seems impossible to create background task from C# DLL in that thread.

Then I read about background tasks in WinRT components and tried to implement that. I used this project as a reference: https://github.com/Microsoft/Windows-universal-samples/tree/93bdfb92b3da76f2e49c959807fc5643bf0940c9/Samples/BackgroundTask/cs/BackgroundTask

In that project, they are triggering the background task from C# app. I don't know how to do it from Cordova app (is it even possible to do it from there?), so I tried to trigger it when one method from WinRT component is called from Java Script proxy. So basically, my background task class exists in WinRT component (like in example) but I am triggering it from WinRT and not from the app. Of course, one more difference is that I used package.windows10.appxmanifest of Cordova app to register background task.

After I do this, I get no compile errors, code for triggering task works and gets executed, but Run method of background task never gets called.

So, my question to you would be: Does anyone know how can I accomplish this thing? How to start the background task in WinRT component or Windows Cordova plugin in general?

Many thanks in advance for any kind of answer.

Cheers


Update #1

Okay, I managed to solve my original issue and here's the code.

I made WinRT component with Dummy.cs class which is entry point for WinJS code and which gets some custom object of mine as parameter. Class looks like this:

using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Runtime.Serialization;
using Windows.Foundation.Collections;
using Windows.ApplicationModel.Background;

namespace DummyWinRT
{
    public sealed class WRTDummy
    {
        private static ApplicationTrigger _trigger;

        public async static void MethodCalledFromWinJS(MyCustomObject myObject)
        {
            await BackgroundExecutionManager.RequestAccessAsync();

            foreach (var t in BackgroundTaskRegistration.AllTasks)
            {
                t.Value.Unregister(true);
            }

            _trigger = new ApplicationTrigger();

            BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
            builder.TaskEntryPoint = "DummyWinRT.BackgroundTaskTest";
            builder.Name = "AppTrigger";
            builder.SetTrigger(_trigger);
            var registration = builder.Register();

            var arguments = new ValueSet();

            try {
                arguments.Add("key1", "value1");
                arguments.Add("key2", "value2");
                arguments.Add("key3", nowWhat);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }

            await _trigger.RequestAsync(arguments);
        }
    }
}

And my Background task looks like this:

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Foundation.Collections;
using Windows.ApplicationModel.Background;
using System.Runtime.InteropServices.WindowsRuntime;

namespace DummyWinRT
{
    public sealed class BackgroundTaskTest : IBackgroundTask
    {
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();

            // If you want to get passed arguments.
            var details = taskInstance.TriggerDetails as ApplicationTriggerDetails;
            var args = details.Arguments as ValueSet;
            var value1 = args["key1"].ToString();
            var value2 = args["key2"].ToString();

            // Do what ever you want.

            _deferral.Complete();
        }
    }
}

New problem I am having is following. When I am "packing" arguments to send to background task, you have maybe noticed this line:

arguments.Add("key3", nowWhat);

In my case, nowWhat is supposed to be delegate. So, either in WinJS or in WinRT I want to declare method which I want to pass to background task to execute it once some logic in there is performed (asynchronous thing).

Arguments which are being passed to background task need to be serializable.

Do you have any idea how can I pass delegate or Action or Func from WinRT to background task so that I can report some stuff from background task back to WinRT? Or if there is any other way to make this happen, I would be interested to hear suggestions?

Thank you in advance.

uerceg
  • 4,637
  • 6
  • 45
  • 63
  • did you finally solve it? Moreover can I do the same wrapper for a C++DLL?? – gts13 Jun 03 '16 at 07:44
  • Not quite, I did find some (for my requirements) solution with extremely limited possibilities, but I didn't find any time to write this thing down. Will write it down eventually once I am back on this task. – uerceg Jun 03 '16 at 11:48

0 Answers0