c# - Parallel.ForEach loop is performing like a serial loop -


i've spent 8+ hours searching online , couldn't find so, here goes.

i'm working team foundation server , c# , i'm trying acquire list of work items , convert them generic object made bound special ui. work items tasks specific day , list 30ish items in size, not big of deal.

the loop looks this:

list<iworkitemdata> workitems = new list<iworkitemdata>(); var queryfordata = store.query(query).cast<workitem>();  if (queryfordata.count() == 0)     return workitems;  parallel.foreach(queryfordata, (wi) => {     var temp = wi;     lock (workitems)     {         tfsworkitemdata tfsworkitem = new tfsworkitemdata(temp);         workitems.add(tfsworkitem);     } }); 

the inside of tfsworkitemdata's constuctor looks this:

public tfsworkitemdata(workitem workitem) {     this.workitem = workitem;      this.fields = new dictionary<string, ifielddata>();      // add fields     foreach (field field in workitem.fields)     {         tfsfielddata fielddata = new tfsfielddata         {             value = field.value,             oldvalue = field.originalvalue,             referencename = field.referencename,             friendlyname = field.name,             valuetype = field.fielddefinition.systemtype         };         this.fields.add(field.referencename, fielddata);     } } 

so takes 90 seconds perform operation. know doesn't take long grab 30 work items must i'm doing cause take long. know lock performance hit, when remove invalidoperationexception saying collection has been modified. when in details of exception, useful info can find collection dictionary. what's weird doesn't me field dictionary in work item being modified @ all. , dictionary in class being added , shouldn't culprit unless i'm missing something.

please me figure out i'm doing wrong regarding dictionaries. did try moving parallel foreach loop workitem.fields collection can't seem work.

edit: read comments of answer answer question. thank you.

please me figure out i'm doing wrong regarding dictionaries.

the exception thrown because list<t> not thread-safe.

you have shared resource needs modified, using parallel.foreach won't help, you're moving bottleneck lock, causing contention there, why you're seeing performance degrade. threads aren't magical solution. need aspire have many independent workers can each own work.

instead, can try using plinq partition enumerable internally. since want project each element in collection, can use enumerable.select:

 var workitems = queryfordata.asparallel().select(workitem => new tfsworkitemdata(workitem)).toarray(); 

in order find out if solution better sequential iteration, benchmark code. never assume more threads faster.


Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -