Since is very common to use coroutines for spawn non blocking asynchronous activities in Caliburn Micro (CM), I wrote a simple base class than executes the computation via a BackgroundWorker and ensure the result “Completed” is fired on the same thread who start the call, typically, but not necessary, the UI thread. Here the class:
public abstract class AbstractBackgroundAction:IResult
{
abstract protected void OnExecute(ActionExecutionContext context);
#region IResult Members
public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
public void Execute(ActionExecutionContext context)
{
using( BackgroundWorker bw = new BackgroundWorker() )
{
Exception exception=null;
bw.DoWork+=(s,e)=>
{
try
{
OnExecute(context);
}
catch (Exception workException)
{
exception = workException;
}
};
bw.RunWorkerCompleted+=(s,e)=>
{
Completed(this, new ResultCompletionEventArgs { Error=exception });
};
bw.RunWorkerAsync();
}
}
#endregion
}
By using the RunWorkerCompleted of the BackgroundWorker we ensure to cam back to the original threads who invoked the coroutine step. Implementer has just to override the function
OnExecute.