在异步操作捕获异常异常、操作

2023-09-03 04:48:50 作者:小闹心° Forever

我读了更多的异步这里:http://msdn.microsoft.com/en-us/library/hh873173(v=vs.110).aspx

I'm reading up more about async here: http://msdn.microsoft.com/en-us/library/hh873173(v=vs.110).aspx

去通过这个例子:

Task<bool> [] recommendations = …;
while(recommendations.Count > 0)
{ 
    Task<bool> recommendation = await Task.WhenAny(recommendations);    
    try
    {
        if (await recommendation) BuyStock(symbol);
        break;
    }
    catch(WebException exc)
    {
        recommendations.Remove(recommendation);
    }
}

我在想,如果我已经在 Task.WhenAny 执行计谋为什么我需要在try块内再等待?

I wonder, if I'm already performing await on Task.WhenAny why do I need to await again inside of the try block?

如果我已经这样做:任务&LT;布尔&GT;推荐=等待Task.WhenAny(建议); 为什么这样做:如果(等待推荐)BuyStock(符号);

If I already did this: Task<bool> recommendation = await Task.WhenAny(recommendations); Why do this: if (await recommendation) BuyStock(symbol);

推荐答案

第一个计谋存在异步等待第一个任务来完成(即建议)。 第二个等待仅在那里提取的实际结果出来已经完成的任务,并引发存储在任务异常。 (需要记住的是等待完成的任务进行了优化,将执行同步很重要的)。

The first await exists to asynchronously wait for the first task to complete (i.e. recommendation). The second await is only there to extract the actual result out of the already completed task, and throw exceptions stored in the task. (it's important to remember that awaiting a completed task is optimized and will execute synchronously).

一个不同的选项来获得的结果将使用任务&LT; T&GT;。结果,但不同之处也处理异常的方式。 等待将抛出的实际的异常(如 WebException ),而任务&LT; T&GT;。结果将抛出一个 AggregateException 里面包含了实际的异常。

A different option to get the result would be using Task<T>.Result, however it differs in the way it handles exceptions. await would throw the actual exception (e.g WebException) while Task<T>.Result would throw an AggregateException containing the actual exception inside.

Task<bool> [] recommendations = …;
while(recommendations.Count > 0)
{ 
    Task<bool> recommendation = await Task.WhenAny(recommendations);    
    try
    {
        if (recommendation.Result) 
        {
            BuyStock(symbol);
        }
        break;
    }
    catch(AggregateException exc)
    {
        exc = exc.Flatten();
        if (exc.InnerExceptions[0] is WebException)
        {
            recommendations.Remove(recommendation);
        }
        else
        {
            throw;
        }
    }
}

显然等待任务更简单,所以它的检索结果出了任务的推荐方法。