gpt4 book ai didi

c# - Parallel.ForEach 未按 C# 中 ConcurrentBag 中的预期添加项目

转载 作者:行者123 更新时间:2023-12-02 14:00:13 26 4
gpt4 key购买 nike

在我的Asp.Net Core WebApi Controller ,我收到 IFormFile[] files 。我需要将其转换为 List<DocumentData> 。我第一次使用foreach 。一切正常。但后来决定改为Parallel.ForEach因为我收到了许多(>5)个文件。

这是我的 DocumentData类(class):

public class DocumentData
{
public byte[] BinaryData { get; set; }
public string FileName { get; set; }
}

这是我的 Parallel.ForEach逻辑:

var documents = new ConcurrentBag<DocumentData>();
Parallel.ForEach(files, async (currentFile) =>
{
if (currentFile.Length > 0)
{
using (var ms = new MemoryStream())
{
await currentFile.CopyToAsync(ms);
documents.Add(new DocumentData
{
BinaryData = ms.ToArray(),
FileName = currentFile.FileName
});
}
}
});

例如,即使有两个文件作为输入,documents总是给出一个文件作为输出。我错过了什么吗?

我最初有List<DocumentData> 。我发现它不是线程安全的,改为ConcurrentBag<DocumentData> 。但我仍然得到了意想不到的结果。请帮忙看看我哪里错了?

最佳答案

我想这是因为,Parallel.Foreach不支持async/await 。只需要 Action作为输入并为每个项目执行它。如果是异步委托(delegate),它将以“即发即忘”的方式执行它们。在这种情况下,传递的 lambda 将被视为 async void功能和async void等不及了。

如果出现过载,需要 Func<Task>然后就可以了。

我建议您创建TaskSelect 的帮助下并使用Task.WhenAll用于同时执行它们。

例如:

var tasks = files.Select(async currentFile =>
{
if (currentFile.Length > 0)
{
using (var ms = new MemoryStream())
{
await currentFile.CopyToAsync(ms);
documents.Add(new DocumentData
{
BinaryData = ms.ToArray(),
FileName = currentFile.FileName
});
}
}
});

await Task.WhenAll(tasks);

此外,您只需返回 DocumentData 即可改进该代码。来自该方法的实例,在这种情况下无需修改 documents收藏。 Task.WhenAll发生过载,需要 IEnumerable<Task<TResult>作为输入并生成 TaskTResult大批。那么,结果就会是这样:

var tasks = files.Select(async currentFile =>
{
if (currentFile.Length > 0)
{
using (var ms = new MemoryStream())
{
await currentFile.CopyToAsync(ms);
return new DocumentData
{
BinaryData = ms.ToArray(),
FileName = currentFile.FileName
};
}
}

return null;
});

var documents = (await Task.WhenAll(tasks)).Where(d => d != null).ToArray();

关于c# - Parallel.ForEach 未按 C# 中 ConcurrentBag 中的预期添加项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60336195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com