我正在使用Windows 8(使用C#),当使用 async 关键字时,我似乎无法很好地处理异常。
该方案涉及启动async
lambda,将其发布到UI线程上运行
执行lambda代码期间发生的异常会在调用线程上重新抛出,无法正确捕获它们。
示例:此代码块在某个工作线程上执行,并尝试在UI线程上安排工作:
await Window.Current.Dispatcher.RunAsync
(CoreDispatcherPriority.Normal
, async () =>
{
var result = await CurrentAppSimulator
.RequestProductPurchaseAsync("product, true);
}
);
如果lambda表达式中的代码抛出异常,则异常不会重新发布回此方法的主体。相反,它是由SynchronizationContext或类似的机制引发的,我似乎无法抓住它。
我想要的是能够从这个代码体(调用代码)中捕获此异常。
这可能吗?
答案 0 :(得分:2)
我认为如果可能的话,你不应该这样做。 UI线程应该是管理后台线程上发生的事情的线程,而不是相反。
如果您确实需要此功能,则可以使用Task.Factory.StartNew()
的重载来指定TaskScheduler
,并使用Unwrap()
将结果Task<Task>
更改为简单Task
:
await Task.Factory.StartNew(
async () =>
await CurrentAppSimulator.RequestProductPurchaseAsync("product", true),
CancellationToken.None, TaskCreationOptions.None, scheduler)
.Unwrap();
或者,您可以使用await await
:
await await Task.Factory.StartNew(
async () =>
await CurrentAppSimulator.RequestProductPurchaseAsync("product", true),
CancellationToken.None, TaskCreationOptions.None, scheduler);
这意味着你需要传递用户界面TaskScheduler
(你可以通过在UI线程上调用TaskScheduler.FromCurrentSynchronizationContext()
)来获取此方法。