优化的火灾和放大器;忘记使用异步/等待和任务放大器、火灾、任务

2023-09-03 06:05:24 作者:输了你赢得世界又如何

我有大约5万件更新。我真的不关心响应(A响应将是不错的,所以我可以登录,但我不想回应是否会花费我的时间。)说了这么多,这是code优化运行尽可能快?如果有5万件,我会运行越来越取消或超时错误任何任务的风险?我得到约1或2响应返回每一秒。

I have about 5 million items to update. I don't really care about the response (A response would be nice to have so I can log it, but I don't want a response if that will cost me time.) Having said that, is this code optimized to run as fast as possible? If there are 5 million items, would I run the risk of getting any task cancelled or timeout errors? I get about 1 or 2 responses back every second.

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。难道我的系统上运行的线程?我能做些什么来避免这种情况?

UPDATE: I am actually getting TaskCanceledExceptions. Did my system run out of threads? What could I do to avoid this?

推荐答案

您的方法将揭开序幕所有任务的同时,这可能不是你想要的。有不会与参与,因为异步操作的没有线程,但有可能是并发连接限制的数量。

You method will kick off all tasks at the same time, which may not be what you want. There wouldn't be any threads involved because with async operations There is no thread, but there may be number of concurrent connection limits.

有可能是更好的工具来做到这一点,但如果你想使用异步/计谋一种选择是使用斯蒂芬Toub的 ForEachAsync 的记载的这篇文章。它可以让你控制你要多少同步操作来执行,这样你就不会超支您的连接限制。

There may be better tools to do this but if you want to use async/await one option is to use Stephen Toub's ForEachAsync as documented in this article. It allows you to control how many simultaneous operations you want to execute, so you don't overrun your connection limit.

下面是从文章:

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));  
}