【问题标题】:WinRT, Javascript and the random "Access denied" exceptionWinRT、Javascript 和随机“拒绝访问”异常
【发布时间】:2013-01-30 09:47:24
【问题描述】:

一些背景

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

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

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

问题

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

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

到目前为止我已经尝试过什么

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

问题...

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

提前致谢

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

【问题讨论】:

  • @markp3rry 这是因为这是一个技术演示,它确实只有一个页面。但我需要打开一些外部网页,我在另一个应用程序页面中完成了它,只有一个 iframe 和主菜单的后退按钮。我认为创建真正导航的努力并不能证明在这个小项目中使用它是合理的......
  • 对不起...那是一个有点愚蠢的评论(我删除了它,但你打败了我)。
  • @markp3rry 没问题的人 :)

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


【解决方案1】:

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

回答我自己的问题:

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

是的,但不是直接

那么,怎么做?

  1. 在 WinRT、C# 组件端,在 C# WinRT 组件中设计一个CancellationTokenSource 属性,并在调用异步操作之前将其分配。
  2. 创建CancellationTokenSource 的实例并将其设置为在调用异步操作之前在上一步中创建的属性。
  3. 在将 .NET 任务转换为 WinRT IAsyncOperation<T> 之前,使用 ContinueWith 方法流畅地继续异步操作,并将作为先前实例化 CancellationTokenSource 的一部分创建的 CancellationToken 提供给 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();

这对我有用!

【讨论】:

    猜你喜欢
    • 2015-05-26
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2011-04-02
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多