我正在尝试创建一种方法,当传递带有可 ping 主机名的数据表引用时,尝试对每个主机执行 ping 操作,然后根据 ping 成功情况更改相应列和行的值。
但是我无法在 Parallel.ForEach 方法中使用引用。有什么办法可以让我完成这项工作吗?
这是我的代码:
public void checkON(ref DataTable PCS)
{
Parallel.ForEach(PCS.AsEnumerable(), pc =>
{
string loopIp = pc["Name"].ToString();
if (PingIP(loopIp))
{
DataRow[] currentpc = PCS.Select("Name = '{0}'", loopIp);
currentpc[0]["Online"] = "ON";
}
else
{
DataRow[] currentpc = PCS.Select("Name = '{0}'", loopIp);
currentpc[0]["Online"] = "OFF";
}
}
);}
最佳答案
除非代码明确表示它是线程安全的,否则您应该假设它不是线程安全的 - 因此访问必须同步。代码中的 ref
没有任何作用。每台 pc
都是一个 DataRow
,因此您可以直接访问它:
string loopIp;
lock(someLockObject) {
loopIp = (string)pc["Name"];
}
string online = PingIP(loopIp) ? "ON" : "OFF";
lock(someLockObject) {
pc["Online"] = online;
}
其中 someLockObject
在所有调用者之间共享,因为您无法对线程模型做出假设:
object someLockObject = new object();
Parallel.ForEach(PCS.AsEnumerable(), pc =>
{ ... });
特别是,您不能只锁定行,因为 DataTable
并不将数据存储在行中(它将数据存储在列中;不,真的)。
关于c# - 在 Parallel.ForEach 循环中更改引用的数据表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22785086/