C# ForEachAsync并向列表或并发集合之外的集合添加项?

C# ForEachAsync并向列表或并发集合之外的集合添加项?,c#,C#,如果在下面的代码中使用ForEachAsync,我应该使用list还是并发集合 var images = new List<Image>(); // or a concurrency collection? await users.ForEachAsync(async u => { Image image = await DownloadImageAsync(u.ImageId); images.Add(image); }); var images=new

如果在下面的代码中使用ForEachAsync,我应该使用list还是并发集合

var images = new List<Image>(); // or a concurrency collection?
await users.ForEachAsync(async u =>
{
    Image image = await DownloadImageAsync(u.ImageId);
    images.Add(image);
}); 
var images=new List();//还是并发集合?
等待用户。ForEachAsync(async u=>
{
Image=wait DownloadImageAsync(u.ImageId);
图片。添加(图片);
}); 

以下是我的做法:

// Create a list of tasks
var imageTasks = new List<Task<Image>>();

// Use ForEachAsync to add tasks to the list
await users.ForEachAsync(u => imageTasks.Add(DownloadImageAsync(u.ImageId)));

// Wait for all tasks to complete
IEnumerable<Image> images = await Task.WhenAll(imageTasks);
//创建任务列表
var imageTasks=新列表();
//使用ForEachAsync将任务添加到列表中
wait users.ForEachAsync(u=>imageTasks.Add(DownloadImageAsync(u.ImageId));
//等待所有任务完成
IEnumerable images=wait Task.WhenAll(imagestasks);

使用
ForEachAsync
的方式存在的问题是,它接受一个不能等待的
操作。这意味着
ForEachAync
很可能在所有
DownloadImageAsync
调用完成之前完成

如果您希望同时执行此操作,而不是使用中间集合,您也可以使用
投影出
DownloadImageAsynctasks
。选择
,然后等待最终结果,即

var images = await Task.WhenAll(users.Select(u => DownloadImageAsync(u.ImageId)));

但是,在使用此技术时,您确实需要对集合中的项目数量有所谨慎。这可能会给下游I/O绑定系统带来大量负载(您可能会被限制),并且在每次下载完成后,每个任务都需要一个线程,以便将每个结果收集到最终集合中。

但DownloadImageAsync会返回一个任务。