AsParallel()和Any()?

时间:2014-08-19 08:38:51

标签: c# .net-4.0 plinq

我看过这段代码使用AsParallel()Any()检查条件:

bool IsAnyDeviceConnected()
{
   return m_devices.Any(d => d.IsConnected);
}

并加快速度:

bool IsAnyDeviceConnected()
{
   return m_devices.AsParallel().Any(d => d.IsConnected);
}

但是看Any()

 internal static bool Any<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
            foreach (T element in source) {
                if (predicate(element)) {
                    return true;
                }
            }
            return false;
        }

我没有看到(显然是) - 它确实关心取消其他工作人员 - 一旦找到

然而 - 这个(其他)代码确实“尽快完成”+取消其他未来的工作:

bool IsAnyDeviceConnected()
{
   var res = Parallel.ForEach(m_devices,
      (d,loopState) => {  
         if (d.IsConnected) 
            loopState.Stop();
      });
   return !res.IsCompleted;
}

问题:

我的诊断程序是否正确? Any() - 一旦找到项目,是否取消其他线程(在AsParallel上下文中)

nb,我担心的是我可能会查看错误的源代码。

3 个答案:

答案 0 :(得分:9)

AsParallel()会返回ParallelQuery,因此,如果您致电AsParallel().Any(...),则不会致电Enumerable.Any,而是ParallelEnumerable.Any

ParallelEnumerable.Any的参考源代码为here

当你挖掘时在AnyAllSearchOperatorEnumerator课程中,您会看到一个名为resultFoundFlag的标记用于tell other workers that a result is found they can stop searching

答案 1 :(得分:5)

您正在查看错误的代码。 AsParallel返回ParallelQuery<TSource>,而ParellelQuery又有Any的重载。

&#39;任何&#39;创建一个新的AnyAllSearchOperator对象并聚合它。如果您深入研究方法调用和对象链,您会发现QueryOpeningEnumerator确实支持取消。


不幸的是,这些特定成员函数的参考源链接被窃听。

答案 2 :(得分:4)

您正在查看错误的代码。 ParallelEnumerable.AsParallel会返回ParallelQuery<>。 ParallelEnumerable还定义了自己的Any扩展方法。

为了指定取消,并行度等,您需要使用ParallelEnumerable的WithXXX扩展方法,如WithCancellationWithDegreeOfParallelism。 ParallelEnumerable.Any不允许您指定这些选项以保留与Enumerable.Any类似的签名