rspec/rules/S6112/vbnet/rule.adoc

82 lines
2.4 KiB
Plaintext
Raw Normal View History

== Why is this an issue?
2021-01-12 16:11:41 +00:00
Subscribing to events without unsubscribing later on can lead to memory leaks or even duplicate subscriptions, i.e. code which is executed multiple times by mistake.
2021-02-02 15:02:10 +01:00
2021-01-12 16:11:41 +00:00
Even if there is no problem right now, the code is more difficult to review and a simple refactoring can create a bug. For example the lifetime of the event publisher could change and prevent subscribers from being garbage collected.
2021-02-02 15:02:10 +01:00
2021-01-27 13:42:22 +01:00
There are patterns to automatically unsubscribe, but the simplest and most readable solution remains to unsubscribe from events explicitly using ``++RemoveHandler++``.
2021-01-12 16:11:41 +00:00
2021-02-02 15:02:10 +01:00
2021-01-27 13:42:22 +01:00
This rule raises an issue when a class subscribes to an even using ``++AddHandler++`` without explicitly unsubscribing with ``++RemoveHandler++``.
2021-01-12 16:11:41 +00:00
=== Noncompliant code example
2021-01-12 16:11:41 +00:00
2022-02-04 17:28:24 +01:00
[source,vbnet]
2021-01-12 16:11:41 +00:00
----
Class MyEventProcucer
Public Shared Event EventFired As EventHandler
End Class
Public Class MyEventSubscriber
Implements IDisposable
Public Sub New()
AddHandler MyEventProcucer.EventFired, AddressOf c_EventFired 'Noncompliant
End Sub
Private Sub c_EventFired(sender As Object, e As EventArgs)
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
End Sub
End Class
----
=== Compliant solution
2021-01-12 16:11:41 +00:00
2022-02-04 17:28:24 +01:00
[source,vbnet]
2021-01-12 16:11:41 +00:00
----
Class MyEventProcucer
Public Shared Event EventFired As EventHandler
End Class
Public Class MyEventSubscriber
Implements IDisposable
Public Sub New()
AddHandler MyEventProcucer.EventFired, AddressOf c_EventFired
End Sub
Private Sub c_EventFired(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
RemoveHandler MyEventProcucer.EventFired, AddressOf c_EventFired
End Sub
End Class
----
== Resources
2021-01-12 16:11:41 +00:00
* https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-subscribe-to-and-unsubscribe-from-events#unsubscribing[How to subscribe to and unsubscribe from events (C# Programming Guide)]
* https://michaelscodingspot.com/5-techniques-to-avoid-memory-leaks-by-events-in-c-net-you-should-know/[5 Techniques to avoid Memory Leaks by Events in C# .NET you should know]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Unsubscribe from this event explicitly with "RemoveHandler".
=== Highlighting
The ``++AddHandler++`` call.
endif::env-github,rspecator-view[]