Parallel ForEach或For循环中的返回值和关键字
从Parallel ForEach或For循环返回值的正确方法是什么?Parallel ForEach或For循环中的返回值和关键字
例如下面的代码是正确的/ threadsafe?
{
Process[] processes = Process.GetProcesses();
String ProcessName = String.Empty;
Parallel.ForEach(processes, curItem => {
if (curItem.Handle == this._handle) {
ProcessName = curItem.ProcessName;
return;
}
});
return ProcessName;
}
还是这个?
{
Process[] processes = Process.GetProcesses();
List<String> ProcessNames = new List<String>();
Parallel.ForEach(processes, curItem => {
ProcessNames.Add(processes.ProcessName);
}
});
return ProcessNames;
}
最后什么回报关键字的并行For或ForEach循环内的行为?
IE:它是否立即终止所有线程?它会导致你可能不期望的任何文物?
希望我所问的是有道理的。 PS:更具体一点。看看第一个例子是我对String线程安全的修改,并且包含我期望的值,因为返回语句?在第二个例子中,我修改了List Collection线程安全吗?我期望添加的所有值都会被添加吗?
我在这里使用PLINQ:
return Process
.GetProcesses()
.AsParallel()
.SingleOrDefault(p => p.Handle == this._handle);
我不知道你在这里处理的数据量是否值得去并行...
更直接地回答你的问题,为了处理从并行循环提前退出时,应该查看将ParallelLoopState交给执行委托的重载。这可以用来控制早期循环终止。
编辑:
您所看到的错误,是因为你的进程没有足够的权限来访问你检查进程的句柄。处理这种蛮力的方法是如下:
Process
.GetProcesses()
//.AsParallel()
.Where(p=>{try{var h=p.Handle;}catch{return false;}return true;})
.SingleOrDefault(p => p.Handle == this._handle)
当然,假设this._handle
是指当前正在执行的进程的句柄:
Process.GetCurrentProcess()
肯定会是更好的选择?
return
在并行foreach循环内基本上与正常循环中的continue
相同,因为return
位于为每个项目执行的委托内部。这意味着它不会终止任何线程,特别是不会终止并行foreach循环的执行。
上述所有答案+的:
如果你想发出信号回路应停止,你应该使用ParallelLoopState
(你可以通过Action<T, ParallelLoopState>
代替Action<T>
代表访问该对象。状态对象具有类似于.Stop()
或.Break()
的方法,这将表示您要停止执行循环(以及其他一些有用的属性,请自行尝试)。
我只是在玩这个概念。我认为它可能不会。 – 2011-03-29 14:06:15
只是我吗?上面的代码会引发以下错误:Win32Exception被用户代码无法处理。访问被拒绝 - 我猜它与比较句柄有关? – 2011-03-29 14:44:08
不是在我的情况,我有我自己的自定义窗口类。它实现了过程对象不提供的功能。我只是想避免另一个API调用并且玩弄这个概念。看起来它在标准循环中也不起作用。哎呦! – 2011-03-29 15:02:42