WinRT,Javascript和随机的“拒绝访问”exception

一些背景

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

JavaScript部分与整个WinRT组件开始一个asynchronous操作:callback函数由JavaScript给出,WinRT在有一些asynchronous结果时调用它。

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

问题

如果在某个页面中调用了整个asynchronous操作,并且您没有导航到其他页面,则一切正常。

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

到目前为止,我已经尝试过

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

这个问题…

我有没有机会通知WinRT组件取消它的asynchronous操作,并且不要试图将控件返回给JavaScriptcallback?

提前致谢

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

  • http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/5f9ebfe6-d652-442d-850d-41bda5e370c9

我发现一些试错后的解决方案。

回答我自己的问题:

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

是的,但不是直接的

又怎样?

  1. 在WinRT中,C#组件端,在C#WinRT组件中设计CancellationTokenSource属性,并在调用异步操作之前分配它。
  2. 创建一个CancellationTokenSource实例,并在调用异步操作之前将其设置为在上一步中创建的属性。
  3. 在将.NET任务转换为WinRT IAsyncOperation<T>之前,用ContinueWith方法ContinueWith执行异步操作,并将CancellationToken作为以前实例化的CancellationTokenSource一部分创建为ContinueWith方法(请参阅取消任务: http : //msdn.microsoft .com / en-us / library / dd997396.aspx )。
  4. 在调用CancellationTokenSource.Cancel()的WinRT组件中实现CancelCurrentAsyncOperation方法。
  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(); 

这对我有效!