HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Action queue in .NET 3.5

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
netqueueaction

Problem

Because I needed to execute some actions one by one in seperate thread (not to block GUI) and I couldn't use Task.ContinueWith from .NET 4.0 I decided to write it by myself.

Here is how it evolved thanks to your suggestions.

```
public class ActionQueue
{
private Thread _thread;
private bool _isProcessed = false;
private object _queueSync = new object();
private readonly Queue _actions = new Queue();
private SynchronizationContext _context;

///
/// Occurs when one of executed action throws unhandled exception.
///
public event CrossThreadExceptionEventHandler ExceptionOccured;

///
/// Occurs when all actions in queue are finished.
///
public event EventHandler ProcessingFinished;

///
/// Gets enqueued actions.
///
public IEnumerable Actions
{
get
{
lock (_queueSync)
{
return new ReadOnlyCollection(_actions.ToList());
}
}
}

protected virtual void Execute()
{
_isProcessed = true;

try
{
while (true)
{
Action action = null;

lock (_queueSync)
{
if (_actions.Count == 0)
break;
else
action = _actions.Dequeue();
}

action.Invoke();
}

if (ProcessingFinished != null)
{
_context.Send(s => ProcessingFinished(this, EventArgs.Empty), null);
}
}
catch (ThreadAbortException)
{
// Execution aborted
}
catch (Exception ex)
{
if (ExceptionOccured != null)
{
_context.Send(s => ExceptionOccured(this, new CrossThreadExceptionEventArgs(ex)), null);
}
}
finally
{
_isProcessed = false;
}

Solution

Since the class itself does very little (runs a bunch of methods on a separate thread), there is little justification in using it, IMHO.

This statement would basically do the same thing (on a ThreadPool, that is):

ThreadPool.QueueUserWorkItem(s =>
{
    SomeMethod();
    DoSomething();
    AndSomeMore();
});


If it included stuff like progress updating, exception handling and finalization events, then it could make more sense to use it:

interface IActionQueue
{
    void Start();

    // if you know the list count, you can provide some progress info
    event Action ProgressChanged;

    // there is no way to catch an exception on a separate thread, so 
    // this would be neat
    event Action ExceptionHappened;

    // this can be useful also
    event Action Finished;
}

Code Snippets

ThreadPool.QueueUserWorkItem(s =>
{
    SomeMethod();
    DoSomething();
    AndSomeMore();
});
interface IActionQueue
{
    void Start();

    // if you know the list count, you can provide some progress info
    event Action<Double> ProgressChanged;

    // there is no way to catch an exception on a separate thread, so 
    // this would be neat
    event Action<Exception> ExceptionHappened;

    // this can be useful also
    event Action Finished;
}

Context

StackExchange Code Review Q#6826, answer score: 4

Revisions (0)

No revisions yet.