I have a Dictionary<string, List<MyObject>>
and I need to run some resource intensive operations on List<MyObject>
. I'm trying to figure out if I can have one thread per key of the Dictionary doing the resource intensive tasks so that each thread updates its key's List. In other words, multiple threads simultaneously updating different items in the dictionary?
Please consider the following simplified pseudo code -
public void MyMethod() {
//The myDict object needs to be shared by all threads.
Dictionary<string, List<MyObject>> myDict = new Dictionary<string, List<MyObject>>();
//GetKeyValue() may return the same key multiple times
foreach(var kv in GetKeyValue()) {
if(myDict.ContainsKey(kv.Key) { myDict[kv.Key].Add(kv.Value); }
else { myDict.Add(kv.Key, kv.Value); }
Task.Factory.StartNew(() => { RunSubsetSum(kv.Key, myDict); });
}
}
//Resource intensive method
public void RunSubsetSum(string key, Dictionary<string, List<MyObject>> myDict) {
//Lock on key so that no two threads run for the same key
lock(key){
foreach(var valueToRemove in GetRemovableObjs())
myDict[kv.Key].Remove(valueToRemove);
}
}
Basically, the idea is that -
- No two threads run for the same key at the same time - Will lock(key) make them queue (run sequentially)?
- All running threads can independently update the same Dictionary - I expect multiple threads to be able to update different items in the same Dictionary simultaneously.
I tried the above approach but results seem to be inconsistent. I think it is because MyMethod() updates the Dictionary for a key for which RunSubsetSum() is already running but not sure how to lock on the key in MyMethod() without interrupting the loop for other keys. I wonder if C# provides simpler solution to this problem. Any thoughts?
Note: I'm considering creating a Dictionary so that I can keep track of which keys are currently being worked upon and updating MyMethod() to buffer the keys until threads finish, but I want to avoid adding this if I can to avoid overcomplicating the logic.