patterncsharpMinor
Action queue in .NET 3.5
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
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;
}
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
If it included stuff like progress updating, exception handling and finalization events, then it could make more sense to use it:
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.