当一个异步
方法,该方法是在等待抛出一个异常,异常存储的地方,并把它扔延迟。在一个WinForms或WPF应用程序,它使用 SynchronizationContext.Current
张贴异常投掷。然而,在例如一个控制台应用程序,它会抛出异常的一个线程池,则会关闭该应用程序。
When an async
method that is awaited upon throws an exception, the exception is stored somewhere and throwing it is delayed. In a WinForms or WPF application, it uses SynchronizationContext.Current
to post throwing of the exception. However, in e.g. a console application, it throws the exception on a thread pool and it brings down the application.
如何从抛出prevent例外异步
殃及的使用方法?
How can I prevent exceptions thrown from an async
method from bringing down the application?
编辑:
Appearantly我所描述的问题,是因为我有无效
异步
的方法。见注释。
Appearantly the issue I'm describing is because I have void
async
methods. See comments.
在异步
启动方法,它抓住了当前的同步内容。一种方法来解决这个问题是要创建自己的同步上下文捕捉异常。
When the async
method is started, it captures the current synchronization context. A way to solve this issue is to create your own synchronization context which captures the exception.
这里的关键是,同步上下文的帖子回调线程池,但它周围的try / catch语句:
The point here is that the synchronization context posts the callback to the thread pool, but with a try/catch around it:
public class AsyncSynchronizationContext : SynchronizationContext
{
public override void Send(SendOrPostCallback d, object state)
{
try
{
d(state);
}
catch (Exception ex)
{
// Put your exception handling logic here.
Console.WriteLine(ex.Message);
}
}
public override void Post(SendOrPostCallback d, object state)
{
try
{
d(state);
}
catch (Exception ex)
{
// Put your exception handling logic here.
Console.WriteLine(ex.Message);
}
}
}
在抓
上面,你可以把你的异常处理逻辑。
In the catch
above you can put your exception handling logic.
其次,每一个线程( SynchronizationContext.Current
是 [ThreadStatic]
)要执行异步
方法与这种机制,则必须将当前的同步方面:
Next, on every thread (SynchronizationContext.Current
is [ThreadStatic]
) where you want to execute async
methods with this mechanism, you must set the current synchronization context:
SynchronizationContext.SetSynchronizationContext(new AsyncSynchronizationContext());
完整主
例如:
class Program
{
static void Main(string[] args)
{
SynchronizationContext.SetSynchronizationContext(new AsyncSynchronizationContext());
ExecuteAsyncMethod();
Console.ReadKey();
}
private static async void ExecuteAsyncMethod()
{
await AsyncMethod();
}
private static async Task AsyncMethod()
{
throw new Exception("Exception from async");
}
}