c# - 处理 .Net 线程中的泄漏

标签 c# .net multithreading

这实际上让我痛苦了几次。如果你做这样简单的代码:

    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);
        }
    }

运行这段代码,观察 handle 飞起来! Thread.Sleep 这样您就可以将其关闭并且它不会接管您的计算机。这应该保证启动的线程在启动下一个线程之前死亡。调用 GC.Collect();什么也没做。根据我的观察,这段代码在正常刷新时每次刷新到任务管理器时都会丢失 10 个句柄。

void SendCEcho() 函数中的内容无关紧要,如果需要,请数到五。当线程终止时,有一个句柄未被清理。

对于大多数程序来说,这并不重要,因为它们不会运行很长时间。在我创建的一些程序中,它们需要连续运行数月。

如果您反复使用此代码,您最终可能会泄漏句柄,导致 Windows 操作系统变得不稳定并且无法运行。需要重新启动。

我确实通过使用线程池和如下代码解决了这个问题:

ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadJobMoveStudy));

但我的问题是,为什么 .Net 中存在这样的漏洞,为什么它存在了这么久?因为喜欢 1.0?我在这里找不到答案。

最佳答案

您正在创建永无止境的线程。 SendCEcho 中的 for 循环永远不会终止,因此线程永远不会结束,因此无法回收。如果我修复了您的循环代码,那么线程将完成并按预期回收。我无法用下面的代码重现问题。

static void SendCEcho()
{
    int Counter = 0;

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

关于c# - 处理 .Net 线程中的泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33882725/

相关文章:

Java的Queue不能指定有限的大小,那么 "add"和 "offer"有什么区别

c# - 如何从 Windows Phone 应用程序启动 IE7?

c# - CA1709 - 我们应该忽略它并使用 Db 还是 DB?

c# - 在禁用的 DataGridView 上显示垂直滚动条

c# - LINQ Datacontext 处理问题

c++ - 在多线程中消耗链表队列

C# FlowDocument 到 HTML 的转换

c# - 如何填充数据表中的每一列

.Net Core Process.在 Linux 上启动

java - 了解线程+异步