我已经看过这个使用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(this IEnumerable source, Func 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上下文中)
嗯,我担心的是我可能会查看错误的源代码.
你看错了代码.AsParallel
返回一个ParallelQuery<TSource>
,并ParellelQuery
有另一个重载Any
.
'任何'创建一个新AnyAllSearchOperator
对象并聚合它.如果你深入研究方法调用和对象链,你会发现它QueryOpeningEnumerator
确实支持取消.
不幸的是,那些特定成员函数的参考源链接被窃听.
AsParallel()
返回a ParallelQuery
,所以如果你打电话给AsParallel().Any(...)
你不打电话Enumerable.Any
,但是ParallelEnumerable.Any
.
对于参考源代码ParallelEnumerable.Any
是在这里.
当您在AnyAllSearchOperatorEnumerator
课堂上挖掘时,您会看到一个被调用的标志resultFoundFlag
用于告诉其他工作人员找到结果,以便他们可以停止搜索.