GC in C# via Godot 4.3 and memory leak with using += operator to signals

Godot Version

4.3

Question

Good day!
I recently started using the += operator to connect signals in code. When I shared this code to another coder, he told me that abusing “+=” to connect signals in code is bad practice. He said that in the long run, - could cause a memory leak, and that I should unlink the signal using the -= operator.
I read an article about it, but what if I want the signal to be connected all the time while the game level is running? When switching between scenes, for example to call another level, will the signal even work if the scene is not active?
Or am I missing something?
If so, when exactly should I unlink the signal using “-=”?

Example where im using += in code

Hello,
I think you should disconnect the signal when the function should no longer be called, for example, when the scene is destroyed or becomes inactive. In my case, I disconnect it in the _ExitTree() method.

In your example, you connect a lambda function, but a lambda function cannot be disconnected using just -=. To fix this, you should extract the function and use a named method instead of an anonymous one, or store the function in a variable.
Example with extracted function:

    private Area2D FloorArea;

    public override void _Ready()
    {
        FloorArea.BodyEntered += Foo();
    }

    public override void _ExitTree()
    {
        FloorArea.BodyEntered -= Foo();
    }

    private Area2D.BodyEnteredEventHandler Foo()
    {
        //todo
    }

When switching between scenes, for example to call another level, will the signal even work if the scene is not active?

Yes.

Here is simple bad example which doesnt work, because these are two different delegate objects. The compiler creates a new instance of the anonymous function each time.

eventHandler += (sender, args) => Console.WriteLine("Event fired!");
eventHandler -= (sender, args) => Console.WriteLine("Event fired!"); // Doesn't work.

I read an article about it, but what if I want the signal to be connected all the time while the game level is running? When switching between scenes, for example to call another level, will the signal even work if the scene is not active?

Why you want to signal be connected if scene is not active?

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.