【发布时间】:2020-05-18 13:27:31
【问题描述】:
我遇到了Parallel.ForEach 的问题。我编写了简单的应用程序,将要下载的文件名添加到队列中,然后使用 while 循环遍历队列,一次下载一个文件,然后在下载文件后,调用另一个异步方法从下载的对象中创建对象memoryStream。该方法的返回结果不等待,直接丢弃,立即开始下一次下载。如果我在对象创建中使用简单的foreach,一切正常 - 在继续下载的同时创建对象。但是,如果我想加快对象创建过程并使用Parallel.ForEach,它将停止下载过程,直到创建对象。 UI 是完全响应的,但它不会下载下一个对象。我不明白为什么会发生这种情况 - Parallel.ForEach 在 await Task.Run() 内部,据我对异步编程的有限了解,这应该可以解决问题。谁能帮我理解为什么它会阻止第一种方法以及如何避免它?
这是一个小示例:
public async Task DownloadFromCloud(List<string> constructNames)
{
_downloadDataQueue = new Queue<string>();
var _gcsClient = StorageClient.Create();
foreach (var item in constructNames)
{
_downloadDataQueue.Enqueue(item);
}
while (_downloadDataQueue.Count > 0)
{
var memoryStream = new MemoryStream();
await _gcsClient.DownloadObjectAsync("companyprojects",
_downloadDataQueue.Peek(), memoryStream);
memoryStream.Position = 0;
_ = ReadFileXml(memoryStream);
_downloadDataQueue.Dequeue();
}
}
private async Task ReadFileXml(MemoryStream memoryStream)
{
var reader = new XmlReader();
var properties = reader.ReadXmlTest(memoryStream);
await Task.Run(() =>
{
var entityList = new List<Entity>();
foreach (var item in properties)
{
entityList.Add(CreateObjectsFromDownloadedProperties(item));
}
//Parallel.ForEach(properties item =>
//{
// entityList.Add(CreateObjectsFromDownloadedProperties(item));
//});
});
}
编辑
这是简化的对象创建方法:
public Entity CreateObjectsFromDownloadedProperties(RebarProperties properties)
{
var path = new LinearPath(properties.Path);
var section = new Region(properties.Region);
var sweep = section.SweepAsMesh(path, 1);
return sweep;
}
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
标签: c# parallel-processing async-await parallel.foreach