这是在 Caliburn.Micro discussions 发布的还。我真的在寻找有关最佳解决方法的建议和意见。
假设我有以下操作
public IEnumerable<IResult> SaveStation()
{
yield return Busy.MakeBusy();
yield return new StationSave(_station);
yield return Busy.MakeNotBusy();
yield return Show.Tab<StationBrowseViewModel>();
}
StationSave 是围绕简单 (WCF) 服务调用的 IResult 包装器。该服务使用 FaultContract/FaultException 来处理故障。
在出现故障的情况下,需要通知用户并且 FaultContract 将包含一些有关出错原因的有用信息。目前 Save 结果捕获异常并将其插入到 Completed 事件的 ResultCompletionEventArgs 中。通过这样做,管道创建的 SequentialResult 被取消(由于错误),从而使屏幕处于忙碌状态。
我真正想要的是关于从错误中恢复(移除忙碌状态)和通知用户的最佳方式的想法(我有几个 IResult 实现,用于我想使用的不同通知样式)故障契约(Contract)中提供的详细信息。通过附加到我的 VM 中的 Completed 事件,我可以得到错误,但此时我不再处于 Action 管道的上下文中,所以我必须使用任何 IResults(MakeNotBusy 和我的显示通知实现)手动执行(而且我必须新建我自己的 ActionExecutionContext,我不想这样做)。
我看过 Marco Amendola 的 Caliburn.Micro 救援过滤器,来自 here ,但我还是无法从 Rescue 方法传回 IResults。
我是否遗漏了一些明显的东西?其他人如何处理这种情况?
最佳答案
两者都是Rob Eisenberg和 Marco Amendola在 CodePlex forum 中提供了可能的解决方案.
我选择从他的 filters implementation 中获取 Marco 的 RescueAttribute
并稍微修改它以允许从 rescue 方法执行进一步的 IResult
。这是对 RescueAttribute.HandleException
protected override bool HandleException(ActionExecutionContext context,
Exception ex)
{
var method = context.Target
.GetType()
.GetMethod(MethodName, new[] { typeof(Exception) });
if (method == null) return false;
try
{
var result = method.Invoke(context.Target, new object[] { ex });
if (result is bool)
return (bool) result;
if (result is IResult)
result = new[] { result as IResult };
if (result is IEnumerable<IResult>)
Coroutine.Execute(((IEnumerable<IResult>) result).GetEnumerator(), context);
else if (result is IEnumerator<IResult>)
Coroutine.Execute(((IEnumerator<IResult>) result), context);
return true;
}
catch
{
return false;
}
}
这允许在我的 VM 中执行以下操作:
public IEnumerable<IResult> Rescue(Exception ex)
{
yield return Busy.MakeNotBusy();
// in practice pass exception details through to notification
yield return new NotificationPopup("Save station failed");
}
[Rescue]
public IEnumerable<IResult> SaveStation()
{
yield return Busy.MakeBusy();
yield return new StationSave(_station);
yield return Busy.MakeNotBusy();
yield return Show.Tab<StationBrowseViewModel>();
}
关于c# - Caliburn.Micro:从 IResult 中的异常中恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4880918/