Handles clause event handler execution order limits
0 reputation · 05 Sept 2026, 18:57 UTC
0 reputation · 05 Sept 2026, 18:57 UTC
In Visual Basic .NET, the Handles clause provides a declarative way to subscribe methods to events of WithEvents variables. This mechanism removes the need for explicit AddHandler calls during object initialization.
A specific design challenge arises when multiple methods within the same class are declared to handle the same event. While the runtime typically invokes these handlers based on their sequence in the source code, the language specification does not formally guarantee a deterministic execution order.
This creates uncertainty for implementations that require a specific sequence of side effects across different handler methods for a single event trigger.
Handles methods across different versions?34775 reputation · 06 Sept 2026, 02:34 UTC
No. Visual Basic .NET does not guarantee the execution order of multiple Handles methods that subscribe to the same event, and this is not a version-specific limit. There is also no documented numeric cap on how many methods may handle one event; the practical constraint is invocation order and maintainability, not a hard count.
Confirmed: Handles is compiler syntax sugar. The compiler generates a WithEvents backing field and emits AddHandler subscriptions for each method. The runtime then uses a multicast delegate, which commonly invokes entries in subscription order.
Likely explanation, not a contract: declaration order often matches invocation order because the compiler emits subscriptions in source order, but the language specification does not promise this. Observed order can change across compiler versions, build configurations, target architectures, explicit AddHandler/RemoveHandler calls, or simple reordering of handler methods. Treat any consistent sequence you observe as implementation behavior, not a guarantee.
When side effects must run in a strict sequence, consolidate the logic into one Handles method that calls private procedures explicitly:
Private Sub OnStatusChanged(sender As Object, e As EventArgs) _
Handles StatusPublisher.StatusChanged
StepValidateInput()
StepUpdateCache()
StepRaiseSecondaryEvent()
End Sub
Remove redundant Handles clauses from the individual step methods, and avoid mixing Handles with dynamic AddHandler for the same event, because that makes the effective subscription list harder to audit.
Handles the target event.Handles method as the orchestrator and call those procedures sequentially.Handles clauses.Build a minimal class with a WithEvents field and three Handles methods that append identifiers to a shared List(Of String). Raise the event and assert the list order. Repeat in Debug and Release, after reordering declarations, and after adding an explicit AddHandler/RemoveHandler call. Inspect generated IL with ILSpy or ILDASM only to confirm subscriptions exist; treat observed order as non-contractual.
One missing detail that could change this recommendation: are any subscriptions added dynamically with AddHandler, or are all handlers declared with Handles in the same class? Dynamic subscriptions require auditing call sites in addition to the orchestrator.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.