In my application I have a set number of actions to preform. I want to designate a specific amount of threads to do the actions. As some action may take longer than others and can be waiting for a response, when the thread finishes I want it to go back to the queue and start the next action. So, as one of the ten threads free up, it gets a new action, so on and so forth until the queue is empty then continue. I need to wait for all the actions to complete before continuing.
So I did some research and testing using TPL which was working great before remembering, "oh crap, I am limited to .Net 2.0 in this application". I've trying to rebuild using only .Net 2.0 but am having no luck. I have virtually no experience with Threading.
Can anyone help me convert this logic into .Net 2.0?
List<int> results = new List<int>();
var stopwatch = Stopwatch.StartNew();
Random random = new Random();
using (BlockingCollection<Action> queue = new BlockingCollection<Action>())
{
for (int i = 0; i < 20; i++)
{
int index = i;
queue.Add(delegate
{
int foo = random.Next(1, 1500);
Thread.Sleep(foo);
results.Add(foo);
Debug.WriteLine(index + " Working: " + foo + " " + Task.CurrentId);
});
}
queue.CompleteAdding();
const int numWorkers = 10;
Task[] tasks = new Task[numWorkers];
for (int i = 0; i < numWorkers; i++)
{
tasks[i] = Task.Factory.StartNew(() =>
{
foreach (Action action in queue.GetConsumingEnumerable())
{
action();
}
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
Task.WaitAll(tasks);
}
Debug.WriteLine("WaitAll took {0} seconds", stopwatch.Elapsed.TotalSeconds);
I'm going to outline how I did this a while ago:
int lastIndex = -1;
Have all the threads do this:
while(true) {
var index = Interlocked.Increment(ref lastIndex);
if (index >= list.Count) return;
ProcessItem(list[index]);
}
Very simple.
Abstract all of this away into a helper method. It should take a delegate so that you don't need to hard-code ProcessItem
.
This helper is actually useful even for .NET 4.5 in cases where you need guaranteed exact degree of parallelism which the thread-pool does not provide.