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

时间:2013-01-30 09:47:24

标签: .net windows windows-8 windows-runtime winjs

一些背景

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

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

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

问题

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

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

到目前为止我尝试了什么

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

问题......

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

提前致谢

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

1 个答案:

答案 0 :(得分:2)

我在一些试错后找到了解决方案。

回答我自己的问题:

  

我是否有机会通知WinRT组件取消它   asynhcronous操作,不要试图将控件返回到   JavaScript回调?

是的,但不是直接

那么,怎么样?

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

    这对我有用!!