Reputation: 53
I'm trying to create a method which when passed a datatable reference with pingable host names, tries to ping each of the hosts and then change the value of corresponding column and row depending on ping success.
However i cannot use references in Parallel.ForEach method. Is there any way i could make this work?
Here's my code:
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";
}
}
);}
Upvotes: 2
Views: 2037
Reputation: 1063774
Unless code explicitly says that it is thread-safe, you should assume it is not - and therefore access must be synchronized. The ref
in your code serves no purpose. Each pc
is a DataRow
, so you can access that directly:
string loopIp;
lock(someLockObject) {
loopIp = (string)pc["Name"];
}
string online = PingIP(loopIp) ? "ON" : "OFF";
lock(someLockObject) {
pc["Online"] = online;
}
where someLockObject
is shared between all of the callers, because you can't make assumptions about the threading model:
object someLockObject = new object();
Parallel.ForEach(PCS.AsEnumerable(), pc =>
{ ... });
In particular, you can't just lock the row because DataTable
doesn't store data in rows (it stores it in columns; no, really).
Upvotes: 3