[英]Rethrowing exceptions in tasks c# without wait
我有一个GUI应用程序,我想在一个任务中运行一些东西,所以它不会保存UI。 我希望将任务中未处理的未处理异常传播到应用程序级异常处理程序。 然而:
我在考虑使用dispatcher.invoke,您怎么看?
public MainWindow()
{
InitializeComponent();
MyMethodAsync();
InitializeA();
IntiializeB();
}
private void MyMethodAsync()
{
Task t = Task.Run(() =>
{
//Do some stuff
throw new Exception("Throwing some unexpected exception");
}).ContinueWith(MyContinueWith);
}
private void MyContinueWith(Task task)
{
if (task.IsFaulted && task.Exception != null)
{
dispatcher.BeginInvoke(new Action(() =>
{
throw task.Exception;
}), null);
}
}
我能想到两种方式。 首先,注册到TaskScheduler.UnobservedTaskException
事件并记录您需要的任何内容:
private void MyMethodAsync()
{
// Note you should probably register only once, so this may not fit here.
TaskScheduler.UnobservedTaskException += (s, e) => GlobalLogger.Log(e);
Task t = Task.Run(() =>
{
// Do some staff
}).ContinueWith(MyContinueWith);
}
由于某种原因你不想使用的更好的选择是实际等待操作并将其包装在try-catch
:
private async Task MyMethodAsync()
{
try
{
await Task.Run(() =>
{
// Do some staff
});
InvokeContinuation();
}
catch (Exception e)
{
// Log.
}
}
要意识到通过调用Task.Run,您通常会产生一个新线程,这可能不是您想要的大多数时间。 在某些你正在进行CPU绑定工作的情况下创建新线程是有意义的,在这种情况下,你需要考虑利用其他并行计算库来充分利用它。 相反,如果您的工作是I / O绑定,您应该能够一直使用异步调用。
为了等待异步方法调用的结果或异常冒泡到调用点,您可以始终将对ContinueWith的调用添加到异步方法返回的任务。 如果您同时处理结果和任何可能的异常,那么async / await语义工作得很好。 但请注意,默认情况下,在这些延续中执行的代码可能不会在与原始线程相同的线程中执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.