gpt4 book ai didi

c# - 对多个任务使用 async/await

转载 作者:IT王子 更新时间:2023-10-29 03:27:53 26 4
gpt4 key购买 nike

我正在使用一个完全异步的 API 客户端,也就是说,每个操作要么返回 TaskTask<T> ,例如:

static async Task DoSomething(int siteId, int postId, IBlogClient client)
{
await client.DeletePost(siteId, postId); // call API client
Console.WriteLine("Deleted post {0}.", siteId);
}

使用 C# 5 async/await 运算符,启动多个任务并等待它们全部完成的正确/最有效的方法是什么:

int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());

或:

int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());

由于 API 客户端在内部使用 HttpClient,我希望它立即发出 5 个 HTTP 请求,并在每个请求完成时写入控制台。

最佳答案

int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());

尽管您与上述代码并行运行操作,但此代码会阻塞运行每个操作的每个线程。例如,如果网络调用需要 2 秒,则每个线程挂起 2 秒,除了等待之外什么都不做。

int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());

另一方面,上面带有 WaitAll 的代码也会阻塞线程,并且您的线程在操作结束之前无法处理任何其他工作。

推荐方法

我更喜欢 WhenAll,它将在并行中异步执行您的操作。

public async Task DoWork() {

int[] ids = new[] { 1, 2, 3, 4, 5 };
await Task.WhenAll(ids.Select(i => DoSomething(1, i, blogClient)));
}

In fact, in the above case, you don't even need to await, you can just directly return from the method as you don't have any continuations:

public Task DoWork() 
{
int[] ids = new[] { 1, 2, 3, 4, 5 };
return Task.WhenAll(ids.Select(i => DoSomething(1, i, blogClient)));
}

为了支持这一点,这里有一篇详细的博客文章,涵盖了所有替代方案及其优点/缺点:How and Where Concurrent Asynchronous I/O with ASP.NET Web API

关于c# - 对多个任务使用 async/await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12337671/

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