一些背景
在过去的几天里,我一直在开发一些 Windows 8 HTML5/WinJS 应用程序。此应用程序使用 WinRT 组件完成一些工作。
JavaScript 部分与整个 WinRT 组件协作启动异步操作:回调函数由 JavaScript 提供,WinRT 在它有一些异步结果时调用它。
我忘了说,整个 Windows 8 应用程序并不是使用单页方法开发的。
问题
如果在某个页面中调用了整个异步操作并且您没有导航到其他页面,那么一切都会按预期进行。
但是,当您导航到其他页面时会发生什么?当 WinRT 组件需要通知 JavaScript 部分异步操作的结果时:ACCESS DENIED EXCEPTION!你的应用程序崩溃了。
到目前为止我尝试了什么
- 整个 WinRT 组件方法返回一个
IAsyncOperation<T>
: 在导航到其他页面之前,我调用了.cancel()
JavaScript 中的方法 => 运气不好 - 我已将回调函数放入
WinJS.Application.sessionState
为了确保整个函数不会被垃圾收集器破坏 => NO LUCK
问题...
我是否有机会通知 WinRT 组件取消它的异步操作并且不要尝试将控件返回给 JavaScript 回调?
提前致谢
你可以看看其他人之前是否发现过同样的问题:
最佳答案
经过一些试错,我找到了解决方案。
回答我自己的问题:
Do I have any chance to notify the WinRT component to cancel it's asynhcronous operation and don't try to return the control to the JavaScript callback?
是的,但不是直接。
那么,怎么办?
- 在 WinRT、C# 组件端,设计一个
CancellationTokenSource
C# WinRT 组件中的属性,并在调用异步操作之前分配它。 - 创建
CancellationTokenSource
的实例并将其设置为在调用异步操作之前在上一步中创建的属性。 - 流利地继续
ContinueWith
将 .NET 任务转换为 WinRT 之前的异步操作方法IAsyncOperation<T>
并给出CancellationToken
作为先前实例化的一部分创建CancellationTokenSource
到ContinueWith
方法(参见取消任务:http://msdn.microsoft.com/en-us/library/dd997396.aspx)。 - 实现
CancelCurrentAsyncOperation
WinRT 组件中将调用CancellationTokenSource.Cancel()
的方法. - 调用之前的
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);
}
}
JavaScript 示例代码:
var component = new MyWinRTComponent();
component.doSomethingAsync().then(function(text) {
// Do stuff
});
// Before navigating to other page
component.cancelCurrentAsyncOperation();
这对我有用!!
关于.net - WinRT、Javascript 和随机 "Access denied"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14600887/