在异步方法中捕获和传播异常

时间:2016-05-01 15:18:33

标签: c# exception-handling async-await task-parallel-library

我在while循环中有以下代码:

Task worker = 
    Task.Factory
        .StartNew(() => 
            {
                ProduceAsync(param, tokenSource.Token);
            }, tokenSource.Token)
        .ContinueWith((t) => 
            { 
                OnException(t); 
            }, TaskContinuationOptions.OnlyOnFaulted);

ProduceAsync看起来像这样:

private async Task ProduceAsync( List<string> param, CancellationToken token)
{
    token.ThrowIfCancellationRequested();
    var task = _requestManager.GetProductsAsync(param);
    var products;
    try
    {
        products = await task;
       _products.Add(products);
    }
    catch
    {
        task.GetAwaiter().GetResult();
    }
}

当异步请求中出现异常时,我希望程序快速失败,所以OnException(t)我正在使用tokenSource取消任务。这里的问题是ProduceAsync没有传播异常并且OnException没有被调用。如何让它传播异常?

注意:我手动将代码复制到手机中,因此可能存在编译错误......

1 个答案:

答案 0 :(得分:2)

我有理由相信

而不是

Task.Factory.StartNew(() =>  { 
   ProduceAsync(param, tokenSource.Token);
}, tokenSource.Token)
.ContinueWith(...
你应该这样做:

Task.Run(async () =>  { 
   await ProduceAsync(param, tokenSource.Token);
}, tokenSource.Token)
.ContinueWith(...

基本上,如果您不等待异步方法完成,那么它将单独运行,并且您传递给Task.Factory.StartNew的代理将立即返回。你也应该使用Task.Run更安全一点。

此外,您可能希望在执行任何所需的异常后,在catch块中使用throw进行重新抛出。