WinRT中的后台任务回调(Cordova Windows插件)

时间:2016-02-24 15:06:31

标签: cordova windows-phone cordova-plugins visual-studio-cordova background-task

我正在为Cordova制作插件,目前我正在尝试使其支持Windows平台。我有一个用C#编写的DLL,我想在我的插件中使用那里的功能。为了做到这一点,我制作了Windows运行时组件项目,这是"包装器"围绕C#DLL,从那里我将方法暴露给Cordova中的Java Script,我可以成功调用它们。那么,

之间的沟通
App <-> Plugin <-> WinRT <-> C# DLL

工作正常。

在某些时候(在C#DLL中的一个方法中)我正在尝试执行以下操作:

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

一旦代码执行到达这一部分,我得出结论,app只是默默地跳过这部分,ProcessQueue()方法永远不会开始在后台任务中执行。首先我认为问题可能与我在C#中启动此任务的方式有关,所以我尝试了几个替换来开始新的后台任务 - 没有运气。

然后我想我可以从后台线程调用Java Script中的插件(我不是Cordova / Java Script专家,你可以从这个假设中看到),但很快意识到它不会发生。我发现作为Cordova插件的一部分对本机代码进行的调用不是在主UI线程中执行,而是在其他一些线程中执行,但仍然无法在该线程中从C#DLL创建后台任务。

然后我阅读了WinRT组件中的后台任务并试图实现它。我使用此项目作为参考:https://github.com/Microsoft/Windows-universal-samples/tree/93bdfb92b3da76f2e49c959807fc5643bf0940c9/Samples/BackgroundTask/cs/BackgroundTask

在该项目中,他们正在从C#app触发后台任务。我不知道如何从Cordova应用程序中执行此操作(甚至可以从那里执行此操作吗?),因此当从Java Script代理调用WinRT组件中的一个方法时,我尝试触发它。所以基本上,我的后台任务类存在于WinRT组件中(如示例中所示),但我是从WinRT而不是从应用程序触发它。当然,另一个区别是我使用Cordova应用程序的package.windows10.appxmanifest来注册后台任务。

执行此操作后,我没有编译错误,触发任务的代码工作并执行,但后台任务的Run方法永远不会被调用。

所以,我的问题是:有谁知道我怎么能完成这件事?如何在WinRT组件或Windows Cordova插件中启动后台任务?

非常感谢任何答案。

干杯

更新#1

好的,我设法解决了我的原始问题,这是代码。

我用Dummy.cs类创建了WinRT组件,这是WinJS代码的入口点,它获取了我的一些自定义对象作为参数。类看起来像这样:

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);
        }
    }
}

我的后台任务看起来像这样:

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();
        }
    }
}

我遇到的新问题如下。当我&#34;包装&#34;发送到后台任务的参数,你可能已经注意到这一行:

arguments.Add("key3", nowWhat);

就我而言,nowWhat应该是delegate。因此,无论是在WinJS还是在WinRT中,我都想声明我想要传递给后台任务的方法,以便在执行某些逻辑后执行它(异步事物)。

传递给后台任务的参数需要为serializable

您是否知道如何将delegateActionFunc从WinRT传递到后台任务,以便我可以将后台任务中的一些内容报告给WinRT ?或者,如果有其他方法可以实现这一点,我会有兴趣听取建议吗?

提前谢谢。

0 个答案:

没有答案