Parallel.ForEachAsync 是.Net6 新增的一个方法,它可以方便的并行执行多个异步方法,最重要的是可以控制最大并发度.这在以前需要通过一些技术方法来实现最大并发度这一点.

一 API定义


public static System.Threading.Tasks.Task ForEachAsync<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Func<TSource, CancellationToken, ValueTask> body);
 
public static System.Threading.Tasks.Task ForEachAsync<TSource>(System.Collections.Generic.IEnumerable<TSource> source, CancellationToken cancellationToken, System.Func<TSource, CancellationToken, ValueTask> body);
 
public static System.Threading.Tasks.Task ForEachAsync<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TSource, CancellationToken, ValueTask> body);
 
public static System.Threading.Tasks.Task ForEachAsync<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource> source, System.Func<TSource, CancellationToken, ValueTask> body);
 
public static System.Threading.Tasks.Task ForEachAsync<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource> source, CancellationToken cancellationToken, System.Func<TSource, CancellationToken, ValueTask> body);
 
public static System.Threading.Tasks.Task ForEachAsync<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TSource, CancellationToken, ValueTask> body);

二 使用示例

//并发设置,这里指定最大并发度为2
var options = new ParallelOptions
{
    MaxDegreeOfParallelism = 2
};

//并发的数据来源
var dataSources = new[] { "https://www.baidu.com","https://www.bing.com","https://www.cnblogs.com","https://www.163.com"  };

//异步方法,获取一个网页内容
async ValueTask GetWebContent(string url, CancellationToken cancellationToken) {
    //延迟一秒,模拟慢速效果
    await Task.Delay(1000,cancellationToken);
    using var httpClient = new HttpClient();
    var       content    = await httpClient.GetStringAsync(url,cancellationToken);
    Console.WriteLine($"[ { DateTime.Now :yyyy-MM-dd HH:mm:ss} ]  {url} ----- {content.Length}");
}

//一句话并发执行
await Parallel.ForEachAsync(dataSources, options , GetWebContent);

打印出来的输出结果,可以看到每一组(2个)的时间基本一致

[ 2022-03-18 23:16:51 ]  https://www.baidu.com                              ----- 9193
[ 2022-03-18 23:16:51 ]  https://www.bing.com                               ----- 76560
[ 2022-03-18 23:16:52 ]  https://www.cnblogs.com                            ----- 69684
[ 2022-03-18 23:16:52 ]  https://www.163.com                                ----- 570429

并上面的并发改成10,再次打印输出结果:

[ 2022-03-18 23:19:44 ]  https://www.baidu.com                              ----- 9193
[ 2022-03-18 23:19:44 ]  https://www.cnblogs.com                            ----- 69684
[ 2022-03-18 23:19:44 ]  https://www.163.com                                ----- 570429
[ 2022-03-18 23:19:44 ]  https://www.bing.com                               ----- 76578

标签: none