user1047016
user1047016

Reputation: 11

How to add datarow value into a Parallel.Foreach loop of arraylist?

Coding:

int rownum = 1;

Parallel.ForEach(listofstaffuid.Cast<object>(), staffuid =>
{
string staffname = dbmanager.GetNameViaUserID(staffuid.ToString());
staffdr = staffdt.NewRow();
staffdr["No"] = rownum;
staffdr["StaffName"] = staffname;
staffdr["RadioList"] = listofradio;
staffdr["RemarkTbx"] = string.Empty;
staffdt.Rows.Add(staffdr);
rownum++;

});

I just want to add my datatable foreach list i find in my arraylist. There is this error saying i already have a datarow hence cannot add. Im stuck now, can someone help me.

Upvotes: 1

Views: 2651

Answers (3)

robert.oh.
robert.oh.

Reputation: 666

When using a counter inside a Parallel.X you'll have to use a threadsafe way of incrementing the counter, e.g. Interlock.Increment.

Also, if you're using fields or variables that have been defined outside the Parallel operation you're running into race conditions. Always try to have a less dependencies to the outer world of the Parallel operation (at least from a writing point of view, or make use of the Concurrent objects (ConcurrentBag ...)).

Upvotes: 0

nvoigt
nvoigt

Reputation: 77354

You have a shared resource, your row counter. You need to syncronize access to your shared resource. On the other hand, a datatable is NOT thread safe for write operations. So you need to syncronize access to your datatable, too.

The only thing that (maybe, that's your part to find out) does not need to be syncronized is your GetNameViaUserID function. Does that function take a long time? If it does, it might be worth a try to get all results from this function in parallel and use the results to fill the datatable sequentially afterwards. If it doesn't take any time at all, using parallel processing doesn't make sense here, as you would need to syncronize your whole code block, wich would mean your foreach would be sequential anyway.

Upvotes: 2

Benny
Benny

Reputation: 317

instead of

staffdr = staffdt.NewRow();

use

var staffdr = staffdt.NewRow();

also rownum will not be correct due to the parallelism

Upvotes: 0

Related Questions