c# - How do I iterate through a dynamically valued dictionary in parallel? -


i trying spawn threads in each loop using copy of value in dict.

my initial understanding foreach create new scope, , led to:

dictionary<string, string> dict = new dictionary<string, string>() { { "sr1", "1" }, { "sr2", "2" } }; foreach (keyvaluepair<string, string> record in dict) {     new system.threading.timer(_ =>     {         console.writeline(record.value);     }, null, timespan.zero, new timespan(0, 0, 5)); } 

which writes

1 2 2 2 

instead of (expected):

1 2 1 2 

so tried cloning kvp in foreach:

keyvaluepair<string, string> tmp = new keyvaluepair<string, string>(record.key, record.value); 

but renders same result.

i've tried system.parallel.foreach seems need values not dynamic, bit of train smash dictionary.

how can iterate through dictionary threads?

the problem closure on lambda, way fix is add local variable inside loop

dictionary<string, string> dict = new dictionary<string, string>() { { "sr1", "1" }, { "sr2", "2" } }; foreach (keyvaluepair<string, string> record in dict) {      var localrecord = record;     new system.threading.timer(_ =>     {         console.writeline(localrecord.value);     }, null, timespan.zero, new timespan(0, 0, 5)); } 

what happening in version captures variable record not value of variable record. when timer runs 2nd time uses "current value" of record 2nd element in array.

behind scenes kinda happening in version of code.

public void mainfunc() {     dictionary<string, string> dict = new dictionary<string, string>() { { "sr1", "1" }, { "sr2", "2" } };     foreach (keyvaluepair<string, string> record in dict) {          _recordstored = record;         new system.threading.timer(annonfunc, null, timespan.zero, new timespan(0, 0, 5));     } }  private keyvaluepair<string, string> _recordstored;  private void annonfunc() {     console.writeline(_recordstored.value); } 

see how when function ran first itteration had correct version of _recordstored, after _recordstored got overwritten show last set value. creating local variable not overwriting.

a way imagine (i not sure how represent in code example) creates _recordstored1 first loop, _recordstored2 2nd loop, , on. function uses correct version of _recordstored# when calls the function.


Comments