Should event handlers in C# ever raise exceptions?

前端 未结 5 722
攒了一身酷
攒了一身酷 2020-12-14 14:59

As a general rule, are there ever any circumstances in which it\'s acceptable for a method responsible for listening to an event to throw an exception (or allow to be thrown

相关标签:
5条回答
  • 2020-12-14 15:11

    Some of the answers here suggest it's bad to throw from an event handler ("creates havoc for your caller", "tends to lead to very difficult to handle situations, and unexpected behavior",...).

    IMHO this is nonsense.

    In the general case, it's perfectly OK to throw from an event handler. Other event handlers won't run of course - neither will the event handler that throws run to the end, nor any other code between the firing of the event and the point where it's caught. So what? It's perfectly normal that code is not executed when an exception is thrown - if you need to guarantee it's executed, then use a finally block.

    Of course in any specific case you may want to consider which, if any, exceptions it is appropriate to handle, just as you would with any other code.

    As always, there are no hard and fast rules that apply in all circumstances. One of the answers here says "event handlers should be fast ... and close to error free...". A counterexample is the ASP.NET Page.Load event.

    A general rule in .NET is that it's almost always a bad idea to swallow all exceptions: this applies to event handlers just as it does to any other code.

    So the answer to the original question "are there ever any circumstances in which it's acceptable for a method responsible for listening to an event to throw an exception" is very definitely yes.

    Just as the answer to the question "are there ever any circumstances in which it's acceptable for a method responsible for listening to an event to swallow exceptions" is also yes.

    0 讨论(0)
  • 2020-12-14 15:13

    The only two types of exceptions that should come out of events are serious, potentially process-ending ones like System.OutOfMemoryException or System.DllNotFoundException, and things that are clearly programming errors, like System.StackOverflowException or System.InvalidCastException. Catching and dropping these kinds of exceptions is never a good idea -- let them float up to the top and let the developer decide what to do with them on an application level.

    As for the rest... any common or garden-variety exception like System.IO.IOException should be handled inside your event, and you should have some mechanism for returning such error conditions to the caller.

    0 讨论(0)
  • 2020-12-14 15:15

    In an ideal word, exceptions should not exist. In a developer real word, exceptions are always expected and should be intercepted (caught), propagated or inhibited as situation asks.

    So

    are there ever any circumstances in which it's acceptable for a method responsible for listening to an event to throw an exception

    Yes. You can expect an exception from every method, responsible or not to an event.

    To catch almost every exception from a Windows application use:
    AppDomain.CurrentDomain.UnhandledException
    Application.ThreadException

    0 讨论(0)
  • 2020-12-14 15:19

    Throwing an exception from a event handler is in many ways similar to throwing an exception from a IDisposable.Dispose method (or a C++ destructor). Doing so creates havoc for your caller because you leave them with little option.

    1. Ignore the exception and let it propagate. This breaks their contract to inform all listeners of an event. This is a very real problem if anyone above them on the stack catches the exception.
    2. Catch it call the other handlers and rethrow. But what happens if one of the others throw as well?
    3. Swallow the exception. This is just bad in general. Event sources should have no knowledge of their caller and hence can't know what they're swallowing.
    4. Crash the process because you're toast.

    Of all of these #4 is the best option. But this is rarely done and can't be counted on.

    I think in your component you really only have a few options

    • You are calling the code which is throwing and are in the best position to handle the exception. If it's not handleable by you then it's unreasonable to expect it to be handled by anyone else. Hence crash the process and be done with it.
    • Don't call the API which throws
    0 讨论(0)
  • 2020-12-14 15:29

    In an ideal world, event handlers shouldn't raise exceptions. Raising an exception in an event handler tends to lead to very difficult to handle situations, and unexpected behavior. As you mentioned- this blocks subsequent event handlers from seeing the event, and the exception propagates into the event producer's code since it raised the event.

    Ideally, event handlers should be fast (if they're long running, they should try to schedule the work in a separate thread) and as close to error free as possible.

    0 讨论(0)
提交回复
热议问题