捕获异步lambda异常

时间:2013-04-26 08:28:58

标签: c# asynchronous windows-8 windows-runtime async-await

我正在使用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或类似的机制引发的,我似乎无法抓住它。

我想要的是能够从这个代码体(调用代码)中捕获此异常。

这可能吗?

1 个答案:

答案 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())来获取此方法。