C# 处理一个事件的多个事件

C# handling multiple events for an Event

我有一个静态 class 来处理 MS SQL 数据库与事件处理程序的交互,如下所示:

public static event EventHandler<SQLExceptionEventArgs> SQLExceptionCaught;

然后我有一个函数来处理它:

 private static void OnSQLExceptionCaught(SqlException e)
{
    if (SQLExceptionCaught != null)
    {
        SQLExceptionCaught(SQLExceptionCaught.Target, new SQLExceptionEventArgs(e));
    }
}

我还有一个继承自 Windows.Forms.Form 的自定义表单,它向该事件处理程序添加了一个委托:

DBHandler.SQLExceptionCaught += this.handleSQLException;

(关闭表单时删除)

然后在每个表单中覆盖此委托。

当只打开一个表单时它工作正常,但我不能让它对多个表单工作所以它只从实际触发事件的表单触发委托。

你能给我指出正确的方向吗?有可能吗?

我很乐意考虑任何其他解决方案,只要它保留此功能。

我觉得您应该将静态 class 变成非静态 class。然后你会有一个 instance 事件,以及 class 的两个实例(每个表单一个)。那时,两个事件处理程序将被适当地分开。从根本上说,您目前的分享不当。

顺便说一句,由于 SQLExceptionCaught 的值在检查之后但在下一行之前变为 null,因此您当前的代码可能会抛出 NullReferenceException。通常你会使用局部变量来解决这个问题:

private static void OnSQLExceptionCaught(SqlException e)
{
    var handler = SQLExceptionCaught;
    if (handler != null)
    {
        handler(SQLExceptionCaught.Target, new SQLExceptionEventArgs(e));
    }
}

关于扩展方法和 C# 6 中引入的 null 条件运算符还有其他选项...有关详细信息,请参阅 my blog post on the topic

您可能发现问题如下:

  • 打开多个表单。
  • OnSQLExceptionCaught.
  • 中设置断点
  • 此时,使用方法GetInvocationList检查事件SQLExceptionCaught的内容。如果它只有一种形式作为订阅者,请检查订阅您的事件的代码。
  • 如果有多个订阅者,并且只调用了一个订阅者,请确保订阅者不会抛出异常。如果在事件调用期间抛出异常,则不会调用其他订阅者。