c# - 将项目异步添加到 foreach 循环中的列表
问题描述
我有一个循环,它从 3rd 方 API 检索对象(因此我必须一次请求每个对象)并将它们添加到一个列表中,然后我从我的过程中返回。它目前按顺序执行这些操作,但我希望循环是异步的以提高性能。
基本代码如下所示:
public async Task<List<ResponseObject<MyClass>>> GetMyClass(string[] references)
{
var responseObject = new ResponseObject<MyClass>();
var responseObjects = new List<ResponseObject<MyClass>>();
foreach (var reference in references)
{
responseObject = await GetExternalData(reference);
responseObjects.Add(responseObject);
}
return responseObjects;
}
我调用的方法定义如下:
public async Task<ResponseObject<MyClass>> GetExternalData(string reference)
我需要如何更改它以使其打开相同的 ReponseObjects 列表,并以并行而不是顺序加载它们?任何帮助将不胜感激。
解决方案
尝试这样做.Select
:
public async Task<List<ResponseObject<MyClass>>> GetMyClass(string[] references)
{
var responseObject = new ResponseObject<MyClass>();
var responseObjects = new ConcurrentBag<ResponseObject<MyClass>>();
var tasks = references.Select(async item =>
{
var responseObject = await GetExternalData(item);
responseObjects.Add(responseObject);
});
await Task.WhenAll(tasks);
return responseObjects.ToList();
}
还有一个AsyncEnumerator NuGet 包,其中包含一个ParallelForEachAsync
与Parallel.ForEach
. references
如果可以有很多对象,我会建议使用这种方法。如上所述,这将产生尽可能多的任务references
。使用ParallelForEachAsync
你可以控制并行度以避免过多的请求,它看起来像这样:
public async Task<List<ResponseObject<MyClass>>> GetMyClass(string[] references)
{
var responseObject = new ResponseObject<MyClass>();
var responseObjects = new ConcurrentBag<ResponseObject<MyClass>>();
await references.ParallelForEachAsync(async item =>
{
var responseObject = await GetExternalData(item);
responseObjects.Add(responseObject);
}, maxDegreeOfParallelism: 8);
return responseObjects.ToList();
}
推荐阅读
- sql - 在 SQL Server 中的 select concat 语句中包含引号
- javascript - 尽管有箭头功能,但在 axios catch 块中未定义“this”
- python - 如何在python中为计数和比例创建聚合?
- vue.js - 返回状态变量的计算属性不是反应性的
- python - 处理从 Instagram 获取隐私帐户的期望值
- javascript - 记住上次悬停的 Div
- delphi - 如何在 TWebBrowser 或 TImage 中加载 base64 加密的 url?
- vue.js - 如何重用应该使用唯一 vuex 存储实例的组件
- azure - 在返回 ServiceBus 消息的 Azure 函数中,如何有条件地返回消息?
- php - Get_Header 在主页 Wordpress 上不起作用 - 几乎所有东西都试过了