任务类 - 多个等待和异常

时间:2014-11-26 11:49:09

标签: c# .net multithreading task-parallel-library

通常我按如下方式封装了一个任务:

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();)此任务,会出现问题。这是允许的吗?如果在任务执行期间出现异常,该如何处理?

2 个答案:

答案 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
}