Unsubscribe from an event

I have the following function.

What does he do, given the control (most likely, this is the form of the window), I want all the controls to contain that are β€œobeying” the Rules (a function showing the controls that I want) to subscribe to an event (say, KeyDown).

The question is: how do I unsubscribe? Or, more importantly, I need ?

Since I will use this in the Load event of forms on the form, do I really need to unsubscribe if the form closes?

(after some easy reading and a little understanding of the GC, I suspect I don't need to unsubscribe, but I'm not sure)

//an example of using the function private void Form1_Load(object sender, EventArgs e) { MyEventHandler.CreateKeyDownEventHandlers(this); } //the function public static void CreateEventHandlers(Control Ctrl) { foreach (Control c in Ctrl.Controls) { //bool Rules(Control) a function that determines to what controls' //events to apply the handler if ( Rules(c) ) { c.KeyDown += (s, e) => { // do something }; } //a control might be a groupbox so we want their contained //controls also if (c.Controls != null) { if (c.Controls.Count > 0) { CreateEventHandlers(c); } } } } 

This is my first attempt with events, delegates, anonymous functions and lambdas, so if I did something really stupid, tell me.

+4
source share
3 answers

Firstly, I think that you cannot cancel an anonymous function if it is not assigned to a handler variable, and this variable is added and removed from the event.

Is it necessary to unsubscribe: think about the lifetime of the object. You create anonymous functions in a static method and attach the controls from which I assume that you control the lifetime.

When you delete one of these controls, they will no longer refer to anonymous functions, and GC can kill them (anonymous functions), so you do not need to unsubscribe.

If the situation was canceled, and something that was created in the static method referred to the controls, as if the control had been added to the event in a static context, then the GC could not take care of the controls until the link for they were deleted, which would not have happened if this had been done in a static method.

+2
source

If you create the form once, and these handlers are also once in the beginning, then you really do not need to clean anything.

If you create it several times, though (for example, you create a form many times when the user clicks a button), then you need to be careful. And here the answer depends on what exactly is in the handlers:

 c.KeyDown += (s, e) => { // do something }; 

In general, assigning a delegate to an event can cause a dependency cycle from the point of view of the GC, for example. Imagine that the form contains the control A and is registered in the event on A. Then the form cannot be deleted until A is selected, and A cannot be deleted until the form is selected (since it is indirect refers to the form via a callback). If you create the form with the A control, then that will be fine (the GC will get rid of both at the same time), but when you create the A controls dynamically, you can end the memory leak.

+2
source

You can unsubscribe from the event using

 yourobject.Yourevent-= YourSubscribedFunction; 

This will cancel this function from the event.

About the second part of your question:

You do not need to unsubscribe if the object containing the event is destroyed.

I'm not sure what will happen if the subscription object is deleted, but my tests show that the function is still being called, although the object no longer exists.

 ClassA a = new ClassA(); using (ClassB b = new ClassB()) // implements IDisposable { b.SubscribeToFoo(a); // b subscribes to FooEvent of ClassA a.DoFoo(); // a executes FooEvent } GC.Collect(); // Run Garbage Collector just to be sure a.DoFoo(); // a executes FooEvent 

The signed ClassB method is called, but at the same time b.

0
source

Source: https://habr.com/ru/post/1298985/


All Articles