5

一些背景

在过去的几天里,我一直在开发一些 Windows 8 HTML5/WinJS 应用程序。该应用程序使用 WinRT 组件完成了一些工作。

JavaScript 部分与整个 WinRT 组件协作启动异步操作:回调函数由 JavaScript 提供,WinRT 在有异步结果时调用它。

我忘了提到整个 Windows 8 应用程序不是使用单页方法开发的。

问题

如果在某个页面中调用了整个异步操作并且您没有导航到其他页面,那么一切都会按预期进行。

但是,当您导航到其他页面时会发生什么?当 WinRT 组件需要通知 JavaScript 部分异步操作的结果时:ACCESS DENIED EXCEPTION!你的应用程序崩溃了。

到目前为止我尝试过的

  • 整个 WinRT 组件方法返回一个IAsyncOperation<T>: 在导航到其他页面之前,我.cancel()在 JavaScript => NO LUCK中调用该方法
  • 我已将回调函数放入WinJS.Application.sessionState以确保垃圾收集器不会破坏整个函数=>没有运气

问题...

我是否有机会通知 WinRT 组件取消它的异步操作并且不尝试将控件返回给 JavaScript 回调?

提前致谢

您可以检查其他人之前是否发现了相同的问题:

4

1 回答 1

2

经过一些试验错误后,我找到了解决方案。

回答我自己的问题:

我是否有机会通知 WinRT 组件取消它的异步操作并且不尝试将控件返回给 JavaScript 回调?

是的,但不是直接的。

又怎样?

  1. 在 WinRT、C# 组件端,CancellationTokenSource在 C# WinRT 组件中设计一个属性,并在调用异步操作之前将其分配。
  2. 创建一个实例CancellationTokenSource并将其设置为在调用异步操作之前在上一步中创建的属性。
  3. ContinueWith在将 .NET 任务转换为 WinRT 之前流畅地继续使用异步操作方法,IAsyncOperation<T>并将CancellationToken创建的作为先前实例化的一部分提供CancellationTokenSource给该ContinueWith方法(请参阅取消任务:http: //msdn.microsoft.com/en-us/library /dd997396.aspx)。
  4. 在 WinRT 组件中实现一个CancelCurrentAsyncOperation方法,该方法将调用CancellationTokenSource.Cancel().
  5. 在导航到另一个页面之前调用 WinJS/JavaScript 中的先前CancelCurrentAsyncOperation方法。

WinRT 组件示例代码:

public sealed class MyWinRTComponent 
{
   private CancellationTokenSource { get; set; }

   public void CancelLastAsyncOperation() 
   {
       if(CancellationTokenSource != null) 
       {
           CancellationTokenSource.Cancel();
       }
   }

   public IAsyncOperation<string> DoSomethingAsync() 
   {
        CancellationTokenSource = new CancellationTokenSource();

        return DoSomethingAsync()
                     .ContinueWith<string>(task => task.Result, CancellationTokenSource);
   }
}

JavaScript 示例代码:

var component = new MyWinRTComponent();
component.doSomethingAsync().then(function(text) {
   // Do stuff
});

// Before navigating to other page
component.cancelCurrentAsyncOperation();

这对我有用!

于 2013-01-30T11:01:44.587 回答