Wednesday 9 December 2009

C# 3.5 Batch Executor

I wanted to have something that would take a load of tasks I had to run, and run them on multiple threads to make them as efficient as possible. The first time I used this I put in 10 web service calls I needed to make. Running them through this sped them up by 50%.

Another feature of this is that it can be run on the main UI (STA) thread as it uses _manualResetEvent.WaitOne(). If you used WaitHandle.WaitAll you'd have to run on the MTA thread, which may not be convenient. I hope you'll agree it's a nice lightweight simple solution to this problem.

Usage as follows:-

var batchExecutor = new BatchExecutor();
_actions.ForEach(action => batchExecutor.AddMethodToExecute(action.Initialise));
batchExecutor.ExecuteAndWaitUntilAllComplete();


Batch Executor class:-

public class BatchExecutor
{
private readonly List _actions;
private readonly ManualResetEvent _manualResetEvent;
private int _methodsLeftToExecute;

public BatchExecutor()
{
_actions = new List();
_manualResetEvent = new ManualResetEvent(false);
}

public void AddMethodToExecute(Action action)
{
_actions.Add(action);
Interlocked.Increment(ref _methodsLeftToExecute);
}

public void ExecuteAndWaitUntilAllComplete()
{
_actions.ForEach(action => ThreadPool.QueueUserWorkItem(o =>
{
action();

if (Interlocked.Decrement(ref _methodsLeftToExecute) == 0)
_manualResetEvent.Set();
}));

_manualResetEvent.WaitOne();
}
}