I think I have found a situation where RescueAttribute is broken. Or maybe I am using co-routines incorrectly.
I have a ViewModel like this:
[Rescue("Rescue")]
class MyViewModel
{
//... left out some bus-logic code here ...
public void Login()
{
yield return Show.Busy();
//the following line will also cause the problem, just like AsyncResult
//yield return Show.MessageBox("Test");
yield return new AsyncResult(() => _server.Login());
//throw new Exception("Aww, snap!");
yield return Show.NotBusy();
}
public void Rescue(Exception exc)
{
//Show a messagebox or something
}
}
AsyncResult is implemented like so:
using Exec = Caliburn.PresentationFramework.Invocation.Execute;
public class AsyncResult : IResult
{
private readonly Action _function;
public AsyncResult(Action function)
{
_function = function;
}
public void Execute(ResultExecutionContext context)
{
Exec.OnBackgroundThread(delegate
{
try
{
_function();
}
catch (Exception exc)
{
Exec.OnUIThread(() => Completed(this, new ResultCompletionEventArgs { Error = exc, WasCancelled = true }));
return;
}
Exec.OnUIThread(() => Completed(this, new ResultCompletionEventArgs()));
});
}
public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
}
If I uncomment the exception in my above ViewModel, Rescue fails to handle the exception.
Is this a bug in Caliburn, or is AsyncResult implemented wrong?
If you put an exception before the yield to return an AsyncResult, Rescue works just fine. Also if the exception is thrown on the async thread, rescue still works!
EDIT: you can also use Show.MessageBox instead of AsyncResult to reproduce the same problem.
It seems a legitimate bug. I added an issue for this in the Caliburn tracker: http://caliburn.codeplex.com/workitem/7636
EDIT: the issue was fixed
see: http://caliburn.codeplex.com/Thread/View.aspx?ThreadId=234229