gpt4 book ai didi

c# - 正确使用 Task.WhenAll

转载 作者:行者123 更新时间:2023-12-02 03:25:12 32 4
gpt4 key购买 nike

我正在尝试理解 async/await 并想知道这是否是 Task.WhenAll 的正确使用方式方法:

public class AsyncLib
{
public async Task<IEnumerable<string>> DoIt()
{
var urls = new string[] { "http://www.msn.com", "http://www.google.com" };

var tasks = urls.Select(x => this.GetUrlContents(x));

var results = await Task.WhenAll(tasks);

return results.Select(x => x);
}

public async Task<string> GetUrlContents(string url)
{
using (var client = new WebClient())
{
return await client.DownloadStringTaskAsync(url);
}
}
}

主要

这是调用控制台应用程序。

class Program
{
static void Main(string[] args)
{
var lib = new AsyncLib();
foreach(var item in lib.DoIt().Result)
{
Console.WriteLine(item.Length);
}
Console.Read();

}
}

最佳答案

当前代码的问题是,如果多个任务抛出,您将无法处理单个异常。

如果这是一个问题,那么可以使用以下方法来处理它们:

public async Task<Task<string>[]> DoIt()
{
var urls = new string[] { "http://www.msn.com", "http://www.google.com" };

var tasks = urls.Select(x => this.GetUrlContents(x)).ToArray();

await Task.WhenAll(tasks);

return tasks;
}

// ...

static void Main(string[] args)
{
var lib = new AsyncLib();
foreach(var item in lib.DoIt().Result)
{
Console.WriteLine(item.Result.Length);
}
Console.Read();

}

请注意,我使用 ToArray() 来避免计算可枚举值并多次启动任务(因为 LINQ 是惰性计算的)。

更新,现在您可以通过消除 async/await 进一步优化 DoIt:

public Task<Task<string>[]> DoIt()
{
var urls = new string[] { "http://www.msn.com", "http://www.google.com" };

var tasks = urls.Select(x => this.GetUrlContents(x)).ToArray();

return Task.Factory.ContinueWhenAll(
tasks,
_ => tasks,
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}

但是,如果您这样做,请注意 exception propagation behavior 中的更改.

关于c# - 正确使用 Task.WhenAll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23621285/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com