Parallel.Foreach() 没有结果

Cod*_*-47 1 c# asynchronous async-await parallel.foreach

我正在尝试使用并行查询 mongo-db,Parallel.Foreach()但没有得到任何结果。但是当我尝试在常规 foreach 循环中运行相同的事情时,我能够执行预期的任务。

var exceptions = new ConcurrentQueue<Exception>();
var secondaryObjectsDictionaryCollection = new Dictionary<string, List<JObject>>();

// This works
foreach(var info in infos)
{
    try
    {
        name = await commonValidator.ValidateAsync(name);
        await commonValidator.ValidateIdAsync(name, id);
        var list = await helper.ListRelatedObjectsAsync(name, id, info, false);

        secondaryObjectsDictionaryCollection.Add(info.PrimaryId, secondaryObjectsList.ToList());
    }
    catch (Exception ex)
    {
        exceptions.Enqueue(ex);
    }
}

//This does not
Parallel.ForEach(infos, async info =>
{
    try
    {
        name = await commonValidator.ValidateAsync(name);
        await commonValidator.ValidateIdAsync(name, id);
        var list = await helper.ListRelatedObjectsAsync(name, id, info, false);

        secondaryObjectsDictionaryCollection.Add(info.PrimaryId, secondaryObjectsList.ToList());
    }
    catch (Exception ex)
    {
        exceptions.Enqueue(ex);
    }
});
Run Code Online (Sandbox Code Playgroud)

我只想并行执行此任务,因为涉及不同的 mongodb 集合并减少响应时间。

我无法弄清楚并行循环中出了什么问题。任何其他并行执行这些任务的方法也可以使用。

小智 6

让我们看一个更简单的例子来说明同样的问题

你有类似的代码

var results = new Dictionary<int, int>();

Parallel.ForEach(Enumerable.Range(0, 5), async index =>
{
  var result = await DoAsyncJob(index);
  results.TryAdd(index, result);
});
Run Code Online (Sandbox Code Playgroud)

您的代码无法运行,因为表达式

async index => {...}
Run Code Online (Sandbox Code Playgroud)

返回未等待的任务

像这样

Parallel.ForEach(Enumerable.Range(0, 5), index => new Task());
Run Code Online (Sandbox Code Playgroud)

顺便说一句,当您像示例中一样使用多线程时,您应该使用ConcurrentDictionary而不是 Dictionary,当您进行并行更新以避免错误和死锁时

这里最好的解决方案是不要使用并行循环,而是使用Task.WhenAll

var tasks = Enumerable.Range(0, 5).Select(async index =>
{
  var result = await DoAsyncJob(index);
  results.TryAdd(index, result);
});

await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)