pzaj
pzaj

Reputation: 1092

C# handling multiple events for an Event

I have a static class to handler MS SQL database interaction with an eventhandler like this:

public static event EventHandler<SQLExceptionEventArgs> SQLExceptionCaught;

then I have a function to handle it:

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

I also have a custom form inherited from Windows.Forms.Form which adds a delegate to that event handler:

DBHandler.SQLExceptionCaught += this.handleSQLException;

(it's removed when form is closing)

and then this delegate is overriden in each form.

It works fine when only one form is open, but I cannot make it work for multiple forms so it only fires the delegate from the form that actually fired the event.

Would you please point me to the right direction on that? Is it even possible?

I'd gladly consider any other solution as long as it preserve this functionality.

Upvotes: 0

Views: 1073

Answers (2)

Martin Mulder
Martin Mulder

Reputation: 12944

You could find the problem as folows:

  • Open multiple forms.
  • Set a breakpoint in your OnSQLExceptionCaught.
  • At that point, check the content of the event SQLExceptionCaught, using the method GetInvocationList. If it has only one form as a subscriber, check your code which is subscribing to your event.
  • It there are more than one subscribers, and only one subscriber is called, make sure that subscriber does NOT throw an exception. If an exception is thrown during the invocation of an event, the other subscribers are not getting called.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499800

It sounds to me like you should turn your static class into a non-static class. Then you'd have an instance event, and two instances of the class (one per form). At that point, the two event handlers would be appropriately separated. Fundamentally, you're sharing inappropriately at the moment.

As an aside, your current code can throw a NullReferenceException due to the value of SQLExceptionCaught becoming null after the check but before the next line. Typically you'd fix this using a local variable:

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

There are other options around extension methods and the null conditional operator introduced in C# 6... see my blog post on the topic for more details.

Upvotes: 4

Related Questions