问题描述
我正在Windows 8(使用C#)上工作,并且当使用 async 关键字时,在某些情况下我似乎无法很好地处理异常.
I am working on Windows 8 (using C#) and when using the async keyword there's a scenario where i can't seem to handle exceptions well.
该方案涉及启动async
lambda,并将其发布以在UI线程上运行.
在执行lambda代码期间发生的异常将重新抛出到调用线程中,而无法正确捕获它们.
The scenario involves launching an async
lambda, posting it to run on the UI thread.
Exceptions that occur during the execution of the lambda code gets re-thrown on the calling thread, with no ability to catch them properly.
示例:此代码块在某些工作线程上执行,并尝试在UI线程上安排工作:
await Window.Current.Dispatcher.RunAsync
(CoreDispatcherPriority.Normal
, async () =>
{
var result = await CurrentAppSimulator
.RequestProductPurchaseAsync("product, true);
}
);
如果lambda表达式中的代码引发异常,则该异常不会重新发布到此方法的主体中.相反,它是由SynchronizationContext或某种类似的机制抛出的,我似乎无法抓住它.
If the code inside the lambda expression throws an exception, the exception is not reposted back to the body of this method. Instead, it is being thrown by the SynchronizationContext or some similar mechanism, and i can't seem to catch it.
我想拥有的功能是能够从这段代码(调用代码)中捕获此异常.
What i'd like to have is the ability to catch this exception from this body of code (the calling code).
这可能吗?
推荐答案
我认为,如果可能的话,您不应该这样做. UI线程应该是管理在后台线程上发生的事情的线程,而不是相反的方法.
I think that if possible, you should not be doing this. The UI thread should be the one that's managing what happens on the background thread(s), not the other way around.
如果确实需要此功能,则可以使用Task.Factory.StartNew()
的重载,它允许您指定TaskScheduler
以及Unwrap()
来将生成的Task<Task>
更改为简单的Task
:
If you really do need this, you can use the overload of Task.Factory.StartNew()
which lets you specify a TaskScheduler
, along with Unwrap()
to change the resulting Task<Task>
into a simple 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);
这意味着您需要将UI TaskScheduler
(可以通过在UI线程上调用TaskScheduler.FromCurrentSynchronizationContext()
来获得)传递给此方法.
This means you need to pass the UI TaskScheduler
(which you can get by calling TaskScheduler.FromCurrentSynchronizationContext()
while you're on the UI thread) to this method.
这篇关于捕获异步lambda异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!