Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle leak in .Net threads

This has actually bitten me a couple times. If you do simple code like this:

    private void button1_Click(object sender, EventArgs e)
    {

        for (int i = 0; i < 1000000; i++)
        {
            Thread CE = new Thread(SendCEcho);
            CE.Priority = ThreadPriority.Normal;
            CE.IsBackground = true;
            CE.Start();
            Thread.Sleep(500);
            GC.Collect();
        }
    }

    private void SendCEcho()
    {
        int Counter = 0;

        for (int i = 0; i < 5; i++)
        {
            Counter++;
            Thread.Sleep(25);
        }
    }

Run this code and watch the handles fly! Thread.Sleep is so you can shut it down and it doesn't take over you computer. This should guarantee that the thread launched dies before the next thread is launched. Calling GC.Collect(); does nothing. From my observation this code loses 10 handles every refresh to the task manager at normal refresh.

It doesn't matter what is in the void SendCEcho() function, count to five if you want. When the thread dies there is one handle that does not get cleaned up.

With most programs this doesn't really matter because they do not run for extended periods of time. On some of the programs I've created they need to run for months and months on end.

If you exercise this code over and over, you can eventually leak handles to the point where the windows OS becomes unstable and it will not function. Reboot required.

I did solve the problem by using a thread pool and code like this:

ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadJobMoveStudy));

My question though is why is there such a leak in .Net, and why has it existed for so long? Since like 1.0? I could not find the answer here.

like image 528
Jake Avatar asked Nov 23 '15 23:11

Jake


1 Answers

You're creating threads that never end. The for loop in SendCEcho never terminates, so the threads never end and thus cannot be reclaimed. If I fix your loop code then the threads finish and are reclaimed as expected. I'm unable to reproduce the problem with the code below.

static void SendCEcho()
{
    int Counter = 0;

    for (int i = 0; i < 5; i++)
    {
        Counter++;
        Thread.Sleep(25);
    }
}
like image 55
Brian Rasmussen Avatar answered Sep 20 '22 22:09

Brian Rasmussen