Dictionary<Action<object>, int> functionsAndArguemnts = new Dictionary<Action<object>, int>
{
{this.LongRunningOp1,1},
{this.LongRunningOp2,2},
{this.LongRunningOp3,3},
};
functionsAndArguemnts.Keys.Select(key =>
{
Thread t = new Thread(new ParameterizedThreadStart(key));
t.Start(functionsAndArguemnts[key]);
return t;
}).ToList().ForEach(thread=>thread.Join());
This showed no performance improvement. I was surprised for a second and then, thankfully I figured it out. I was a victim of the power of the yield return. The select will yield return the results and so each thread would only start when we tryed to join to it. Doh! Easy enough to fix though:
functionsAndArguemnts.Keys.Select(key => { Thread t = new Thread(new ParameterizedThreadStart(key)); t.Start(functionsAndArguemnts[key]); return t; }).ToList().ForEach(thread=>thread.Join()); So the next way I screwed up my parallization was a bit less subtle. I had a function that handled all the synchronization and error handling (the error handling bit I left out of this example) for some threading I was doing. It takes in a function and a argument and calls the function with the argument and then puts all the results in a list. private List<int> ints = new List<int>(); public void DoStuff(Func<string, IEnumerable<int>> action, string argument) { lock (this.ints) { this.ints.AddRange(action(argument)); } } Once again, silly me. No parallization is happening. And once again easy fix: public void DoStuff(Func<string, IEnumerable<int>> action, string argument) { IEnumerable<int> results = action(argument); lock (this.ints) { this.ints.AddRange(results); } } The moral of the story, parallization is still hard. An interesting link on some lock trivia that highlights the point: Locks and exceptions don't mix. I am looking forward to the work in C# 4.0 around threading, would make some things simpler.
0 comments:
Post a Comment