c# - Caliburn.Micro:从 IResult 中的异常中恢复

标签 c# silverlight silverlight-4.0 caliburn.micro

这是在 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 EisenbergMarco AmendolaCodePlex 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/

相关文章:

c# - 从其他表单调用时,DataGridView.DataSource 返回空 DataTable

c# - 如何强制 visual studio 调试器跳过特定的异常?

c# - 如何使用 MediaStreamSource 播放原始广告 AAC 流?

c# - 如何减少我的代码,几乎相同的结构数量可能非常多

wpf - 在服务器端从 Silverlight 4 XAML 生成图像,而无需在浏览器中呈现 UI

c# - WPF 将内容展开到窗口外

c# - StreamReader ReadLineAsync 忽略回车并挂起

silverlight - 超过了 2083 的最大 URI 长度

silverlight - 如何创建同时支持深色和浅色主题的画笔?

c# - 需要返回带有货币符号的值