uer*_*ceg 8 windows-phone cordova cordova-plugins background-task visual-studio-cordova
我正在为Cordova制作插件,目前我正在尝试使其支持Windows平台.我有一个用C#编写的DLL,我想在我的插件中使用那里的功能.为了做到这一点,我创建了Windows运行时组件项目,该项目围绕C#DLL"包装",并从那里我将方法暴露给Cordova中的Java Script,我可以成功调用它们.所以,之间的沟通
App <-> Plugin <-> WinRT <-> C# DLL
Run Code Online (Sandbox Code Playgroud)
工作得很好.
在某些时候(在C#DLL中的一个方法中)我试图做以下事情:
Task.Factory.StartNew(() => ProcessQueue(), TaskCreationOptions.LongRunning);
Run Code Online (Sandbox Code Playgroud)
一旦代码执行到达这一部分,我得出结论,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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的后台任务看起来像这样:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的新问题如下.当我"打包"参数发送到后台任务时,你可能已经注意到这一行:
arguments.Add("key3", nowWhat);
Run Code Online (Sandbox Code Playgroud)
在我的情况下,nowWhat应该是delegate.因此,无论是在WinJS还是在WinRT中,我想要声明我想要传递给后台任务的方法,以便在执行某些逻辑时执行它(异步事物).
传递给后台任务的参数需要serializable.
你有什么想法,我怎么可以通过delegate或Action或Func从WinRT的背景任务,这样我可以报告来自后台任务回到WinRT的一些东西?或者,如果有任何其他方法可以实现这一点,我会有兴趣听取建议吗?
先感谢您.
| 归档时间: |
|
| 查看次数: |
629 次 |
| 最近记录: |