代码之家  ›  专栏  ›  技术社区  ›  Joel in Gö

如何停止异常破坏我的委托链?

  •  8
  • Joel in Gö  · 技术社区  · 17 年前

    我遇到了一个常见的问题。当我有一个可能由几个不同类订阅的事件时,其中一个类引发的异常将终止回调链;由于我不知道回调的执行顺序,这可能会导致某些类的状态发生不可预测的变化,而不是其他类。

    CLR via C# ,我正在使用C#2.0)有一小段关于使用 MulticastDelegate.GetInvocationList 为了逃避这件事,但仅此而已。所以我的问题是:处理这个问题的最好方法是什么?我必须使用吗 MulticastDelegate.GetInvocationList

    谢谢

    2 回复  |  直到 17 年前
        1
  •  12
  •   Marc Gravell    17 年前

    如果只调用委托,它将按顺序调用所有目标方法。你需要使用 GetInvocationList

    • 查证 Cancel 之后
    • 获取每个属性的返回值

    至于使用它的最佳方式:你希望它表现如何?我不清楚。。。例如,这可能非常适合扩展方法:

    static void InvokeIgnoreErrors(this EventHandler handler,
            object sender) {
        if(handler != null) {
            foreach(EventHandler subHandler in handler.GetInvocationList()) {
                subHandler(sender, EventArgs.Empty);
            }
        }
    }
    

    那你就可以打电话了 myHandler.InvokeIgnoreErrors(this);

    另一个例子可能是:

    static bool InvokeCheckCancel(this CancelEventHandler handler,
            object sender) {
        if(handler != null) {
            CancelEventArgs args = new CancelEventArgs(false);
            foreach(CancelEventHandler subHandler in handler.GetInvocationList()) {
                subHandler(sender, args);
                if(args.Cancel) return true;
            }
        }
        return false;
    }
    

    在第一个事件请求取消后停止。

        2
  •  1
  •   Helen Toomik    17 年前

    我认为您应该检查事件处理程序,而不是更改调用事件的方式。在我看来,事件处理程序方法的编写应该始终确保它们是“安全的”,并且永远不会让异常传播。当您在GUI代码中处理事件时,这一点尤其重要,因为事件是由外部代码调用的,但这是一个始终保持的好习惯。