我看过这段代码使用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,我担心的是我可能会查看错误的源代码。
答案 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扩展方法,如WithCancellation和WithDegreeOfParallelism。 ParallelEnumerable.Any不允许您指定这些选项以保留与Enumerable.Any
类似的签名