在Parallel.ForEach循环中对引用的数据表进行更改

时间:2014-04-01 11:52:55

标签: c# datatable ref parallel.foreach

我正在尝试创建一个方法,当使用可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";
                }
            }
        );}

1 个答案:

答案 0 :(得分:3)

除非代码明确说明它是线程安全的,否则你应该认为它不是 - 因此必须同步访问。代码中的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不会将数据存储在行中(它将其存储在列中;不,确实如此)。