优化的火灾和放大器;忘记使用异步/等待和任务 [英] Optimizing for fire & forget using async/await and tasks

查看:153
本文介绍了优化的火灾和放大器;忘记使用异步/等待和任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大约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));  
}

这篇关于优化的火灾和放大器;忘记使用异步/等待和任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆