我有大约 500 万个项目需要更新。我并不真正关心响应(如果有响应就好了,这样我就可以记录它,但如果这会花费我时间,我不想要响应。)话虽如此,这段代码是否经过优化以运行尽可能快?如果有 500 万个项目,我是否会面临任务取消或超时错误的风险?我每秒大约收到 1 或 2 个回复。
var tasks = items.Select(async item =>
{
await Update(CreateUrl(item));
}).ToList();
if (tasks.Any())
{
await Task.WhenAll(tasks);
}
private async Task<HttpResponseMessage> Update(string url)
{
var client = new HttpClient();
var response = await client.SendAsync(url).ConfigureAwait(false);
//log response.
}
更新: 我实际上收到了 TaskCanceledExceptions。我的系统是否耗尽了线程?我该怎么做才能避免这种情况?
最佳答案
您的方法将同时启动所有任务,这可能不是您想要的。不会涉及任何线程,因为使用 async
操作 There is no thread ,但可能存在并发连接数限制。
可能有更好的工具可以做到这一点,但如果您想使用 async/await,一个选择是使用 Stephen Toub 的 ForEachAsync
,如 this article 中所述。 。它允许您控制要执行的同时操作数,这样您就不会超出连接限制。
这是文章中的内容:
public static class Extensions
{
public static async Task ExecuteInPartition<T>(IEnumerator<T> partition, Func<T, Task> body)
{
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select ExecuteInPartition(partition, body));
}
}
用法:
public async Task UpdateAll()
{
// Allow for 100 concurrent Updates
await items.ForEachAsync(100, async t => await Update(t));
}
关于c# - 使用异步/等待和任务优化即发即忘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25520254/