应该等待Parallel.Foreach吗?

时间:2015-02-12 16:54:12

标签: c# asynchronous task-parallel-library

这里发生了一件奇怪的事情。我以为Parallel.Foreach会等到所有任务完成后再继续。但是,我有类似的东西:

List<string> foo(List<A> list){
    Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
    Parallel.Foreach(list, element =>
    {
        dictionary[element.Id] = true;
        if (element.SomeMethod()){
            dictionary[element.Id] = false;
        }
    });

    List<string> selectedIds = (from element in list where !dictionary[element.Id] select element.Id).ToList();
    return selectedIds;
}

然后我在选择行中收到System.Collections.Generic.KeyNotFoundException(有时,并不总是)。正如您所看到的,我正在为每个可能的键(列表元素的ID)初始化字典,然后获得此异常,这使我认为在执行并行之前可能会到达此行.Foreach完成了......是吗?如果是这样,我怎么能等到这个Parallel.Foreach的所有分支完成?

1 个答案:

答案 0 :(得分:9)

Parallel.Foreach不需要等待,因为它不会返回Task并且不是异步的。当对该方法的调用完成时,迭代已经完成。

但是,Parallel.Foreach同时使用多个线程,Dictionary不是线程安全的。

您可能手上有竞争条件,而您应该使用线程安全ConcurrentDictionary


通过使用PLinq&#39; AsParallel可以更简单的方式解决这个具体案例:

list.AsParallel().Where(element => !element.SomeMethod());