我想创建一些自定义事件,它们将始终以事件注册的相反顺序调用已注册的事件处理程序,即始终首先调用最近注册的事件处理程序。可能吗? Business Layer类将在某些错误条件下引发这些事件,其中已注册的事件处理程序可能能够克服错误情况。
这是一个纯粹的技术问题,是否有可能这样做?是否可以覆盖事件链调用顺序?该语言(任何版本的C#2.0,3.0,4.0)是否支持此功能?
修改
可能的用法是用于错误报告和错误恢复。示例,Func A调用Func B调用Func C.Func C可能会遇到错误情况并且有一个事件。如果Func A和Func B能够提供错误恢复机制,则它们将注册该事件。由于Func B更有可能具有解决错误的上下文,我想调用最新的注册处理程序并检查事件args以查看错误是否已解决。如果是的话,我甚至不会打电话给其他事件处理程序。如果不是,我将调用第二个最近注册的处理程序,它将是调用者的调用函数,即Func A.
在大多数情况下,代码通常以如下方式构造:如果Func A调用Func B,则Func B不调用Func A,即循环调用通常不存在,并且事件处理程序的顺序与函数顺序相同调用。因此,如果Func A调用调用Func C的Func B,并且Func C引发“错误事件”,则处理错误的最合适的候选者是Func B的事件处理程序,然后是Func A的事件处理程序,依此类推。
它类似于堆栈跟踪的展开,并为最近的调用者函数提供了使用该事件的机会。没有。可能存在调用函数。
任何处理程序成功使用事件后,引发“错误事件”的Func C将继续。它将检查Event args以确定这一点。如果没有处理程序消耗该事件,Func C将抛出异常。
答案 0 :(得分:4)
是的,您可以使用MulticastDelegate.GetInvocationList()方法自行迭代事件的调用列表。像这样:
public event EventHandler Custom;
protected virtual void OnCustom(EventArgs e) {
var handler = Custom;
if (handler != null) {
var subscribers = handler.GetInvocationList();
for (int ix = subscribers.Length - 1; ix >= 0; --ix) {
var sub = (EventHandler)subscribers[ix];
sub(this, e);
}
}
}
请注意,这是一个不确定的解决方案,您无法控制其他代码订阅该事件的顺序。