Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Parallel.ForEach循环中对引用的datatable进行更改_C#_Datatable_Ref_Parallel.foreach - Fatal编程技术网

C# 在Parallel.ForEach循环中对引用的datatable进行更改

C# 在Parallel.ForEach循环中对引用的datatable进行更改,c#,datatable,ref,parallel.foreach,C#,Datatable,Ref,Parallel.foreach,我试图创建一个方法,当传递一个带有可ping主机名的datatable引用时,该方法会尝试ping每个主机,然后根据ping成功情况更改相应列和行的值 但是,我不能在Parallel.ForEach方法中使用引用。有没有办法让这一切顺利 这是我的密码: public void checkON(ref DataTable PCS) { Parallel.ForEach(PCS.AsEnumerable(), pc => {

我试图创建一个方法,当传递一个带有可ping主机名的datatable引用时,该方法会尝试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
不在行中存储数据(它在列中存储数据;不,真的)。

那么为什么需要
ref
?从你的代码我看不出原因。此外,
DataTable
线程安全吗?(我想应该是这样,但是……我们确定吗?@Adriano我很确定不是这样;是的,这是正确的。真的谢谢你的帮助。被困在这里很长时间了。初学者:D但是我有一些问题,如果你可能:)为什么尝试这样做。在并行循环中从datatable中选择它找不到相应的行。另一个问题是,实现此功能的最佳方式是什么,这样它就不会锁定UI线程,并且对datatable的更改将实时可见。此datatable用作DataGridView控件的数据源。@dazgen
datatable
发布更改通知;因此,当您从其他线程进行更改时,让它主动连接是一个非常糟糕的主意。。。但为了不冻结,还是一如既往地遵循同样的规则:不要阻塞UI线程——请注意,因为
Parallel.ForEach
是一个同步调用(它会阻塞直到所有调用完成),所以阻塞UI线程正是您要做的。