I have 3 questions concerning events:
I have for example this code:
Ctor: Purpose: For database property updates
this.PropertyChanged += (o, e) => { switch (e.PropertyName) { case "FirstName": break; case "LastName": break; } };
and this: Purpose: For GUI-binding wrap the model into viewmodels
ObservableCollection<Period> periods = _lpRepo.GetDailyLessonPlanner(data.DailyDate); PeriodListViewModel = new ObservableCollection<PeriodViewModel>(); foreach (Period period in periods) { PeriodViewModel periodViewModel = new PeriodViewModel(period,_lpRepo); foreach (DocumentListViewModel documentListViewModel in periodViewModel.DocumentViewModelList) { documentListViewModel.DeleteDocumentDelegate += new Action<List<Document>>(OnDeleteDocument); documentListViewModel.AddDocumentDelegate += new Action(OnAddDocument); documentListViewModel.OpenDocumentDelegate += new Action<int, string>(OnOpenDocument); } PeriodListViewModel.Add(periodViewModel); }
In order to prevent resource leaks, you should unsubscribe from events before you dispose of a subscriber object. Until you unsubscribe from an event, the multicast delegate that underlies the event in the publishing object has a reference to the delegate that encapsulates the subscriber's event handler.
Event listeners can also be removed by passing an AbortSignal to an addEventListener() and then later calling abort() on the controller owning the signal.
Well, let's take the last question first. You can't reliably unsubscribe from an event that you've subscribed to directly with a lambda expression. You either need to keep a variable around with the delegate in (so you can still use a lambda expression) or you need to use a method group conversion instead.
Now as for whether you actually need to unsubscribe, it depends on the relationship between the event producer and the event consumer. If the event producer should live for longer than the event consumer, you should unsubscribe - because otherwise the producer will have a reference to the consumer, keeping it alive for longer than it should be. The event handler will also keep getting called for as long as the producer produces it.
Now in many cases that's not a problem - for example, in a form the button that raises the Click
event is likely to live for about as long as the form on which it's created, where the handler is typically subscribed... so there's no need to unsubscribe. This is very typical for a GUI.
Likewise if you create a WebClient
solely for the purpose of a single asynchronous request, subscribe to the relevant event and start the asynchronous request, then the WebClient
itself will be eligible for garbage collection when the request has finished (assuming you don't keep a reference elsewhere).
Basically, you should always consider the relationship between the producer and the consumer. If the producer is going to live longer than you want the consumer to, or it's going to continue raising the event after you're no longer interested in it, then you should unsubscribe.
1) It depends. Usually it's a good idea, but there are typical cases where you don't need to. Basically, if you are sure that the subscribing object is going to outlive the event source, you ought to unsubscribe, otherwise this would create an unnecessary reference.
If however your object is subscribing to its own events, like in the following:
<Window Loaded="self_Loaded" ...>...</Window>
--then you don't have to.
2) Subscribing to an event makes additional reference to the subscribing object. So if you don't unsubscribe, your object might be kept alive by this reference, making effectively a memory leak. By unsubscribing you are removing that reference. Note that in the case of self-subscription the problem doesn't arise.
3) You can do like that:
this.PropertyChanged += PropertyChangedHandler; ... this.PropertyChanged -= PropertyChangedHandler;
where
void PropertyChangedHandler(object o, PropertyChangedEventArgs e) { switch (e.PropertyName) { case "FirstName": break; case "LastName": break; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With