我遇到了一个常见的问题。当我有一个事件可能被几个不同的类订阅时,其中一个类抛出的异常将杀死回调链;由于我不知道回调的执行顺序,这可能导致某些类而不是其他类的不可预测的状态更改。
在圣经中(CLR via C#,我用的是c 2.0),有一小段是关于用MulticastDelegate.GetInvocationList
来解决这个问题的,但是没有更多。所以我的问题是:处理这个问题的最佳方法是什么?每次有活动我都要使用MulticastDelegate.GetInvocationList
吗??或者我需要将所有可以作为委托链的一部分调用的方法封装在某种回滚机制中?为什么所有这些选项与简单的事件/委托模型(在c_中很容易使用)相比都那么复杂?我怎么能用这种简单的方法而不被破坏呢?
谢谢!
最佳答案
如果您只是调用委托,它将按顺序调用所有目标方法。如果要单独执行它们,则需要使用GetInvocationList
-例如:
每次检查后
获取每个
在单个目标失败后继续
至于最好的使用方法:你希望它如何表现?我不清楚…例如,这可能非常适合扩展方法:
static void InvokeIgnoreErrors(this EventHandler handler,
object sender) {
if(handler != null) {
foreach(EventHandler subHandler in handler.GetInvocationList()) {
subHandler(sender, EventArgs.Empty);
}
}
}
然后您可以直接调用
Cancel
(例如)。另一个例子可能是:
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;
}
在第一个事件请求取消后停止。