76 lines
2.3 KiB
Plaintext
76 lines
2.3 KiB
Plaintext
== Why is this an issue?
|
|
|
|
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.
|
|
|
|
|
|
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.
|
|
|
|
|
|
There are patterns to automatically unsubscribe, but the simplest and most readable solution remains to unsubscribe from events explicitly using ``++RemoveHandler++``.
|
|
|
|
|
|
This rule raises an issue when a class subscribes to an even using ``++AddHandler++`` without explicitly unsubscribing with ``++RemoveHandler++``.
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,vbnet]
|
|
----
|
|
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
|
|
|
|
[source,vbnet]
|
|
----
|
|
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
|
|
|
|
* 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)
|
|
|
|
include::message.adoc[]
|
|
|
|
include::highlighting.adoc[]
|
|
|
|
endif::env-github,rspecator-view[]
|