WinRT,Javascript和随机的"拒绝访问"异常

Mat*_*zer 5 .net windows windows-8 windows-runtime winjs

一些背景

在过去的几天里,我一直在开发一些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去,以确保整个函数不被垃圾收集器破坏=> NO LUCK

问题......

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

提前致谢

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

Mat*_*zer 2

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

回答我自己的问题:

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

是的,但不是直接的

又怎样?

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

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

JavaScript 示例代码:

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

// Before navigating to other page
component.cancelCurrentAsyncOperation();
Run Code Online (Sandbox Code Playgroud)

这对我有用!