通常我按如下方式封装了一个任务:
Task t = Task.Factory.StartNew(() =>
{
func_can_throw_exception();
}, token).
ContinueWith
((task) =>
{
try
{
task.Wait();
}
catch (AggregateException ae)
{
ae.Handle((x) =>
{
//handle
return true;
});
}
finally
{
}
});
如果我在一个单独的线程(例如GUI线程)中等待(t.Wait();
)此任务,会出现问题。这是允许的吗?如果在任务执行期间出现异常,该如何处理?
答案 0 :(得分:1)
Task.Run(() => {
func_can_throw_exception();
})
.ContinueWith(task => {
do_something_with(task.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
但在您提供的代码task.Wait()
中,由于ContinueWith
仅在任务完成后触发,因此不会阻止。
在一般情况下,task.Wait()
将阻止当前线程,直到任务完成。如果任务失败,则Wait
将抛出AggregateException
。但是,如果您不小心,使用Wait
会导致死锁。最好在TPL代码中使用continuation。
答案 1 :(得分:0)
Wait
执行任务通常是一个坏主意,因为它会阻塞调用线程,而不是异步等待的await
。阻止GUI线程特别危险,因为它很快就会导致死锁。
您正在内部处理任何异常,因此除非Handle
抛出异常,否则t.Wait()
不会抛出异常。
您应该做的是使用async-await
:
try
{
await Task.Run(() => func_can_throw_exception());
}
catch (Exception e)
{
// handle exception
}