Ich glaube, ich habe eine Situation gefunden, in der RescueAttribute defekt ist. Oder vielleicht verwende ich Co-Routinen falsch.
Ich habe ein ViewModel wie dieses:
[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 ist folgendermaßen implementiert:
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 { };
}
Wenn ich die Ausnahme in meinem obigen ViewModel auskommentiere, kann Rescue die Ausnahme nicht behandeln.
Ist dies ein Fehler in Caliburn, oder ist AsyncResult falsch implementiert?
Wenn Sie eine Ausnahme vor dem Yield setzen, um ein AsyncResult zurückzugeben, funktioniert Rescue einwandfrei. Auch wenn die Ausnahme ausgelöst wird auf den asynchronen Thread, die Rettung funktioniert immer noch!
EDIT: Sie können auch Show.MessageBox anstelle von AsyncResult verwenden, um das gleiche Problem zu reproduzieren.