这个问题其实困扰了我好几次。如果你写的代码像这样简单:
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);
}
}
运行这段代码并观察句柄的变化!Thread.Sleep是为了让你能够关闭它并防止它占用电脑。这应该保证启动的线程在下一个线程启动之前结束。调用GC.Collect(); 没有效果。从我的观察来看,这段代码每次在任务管理器上正常刷新时都会丢失10个句柄。
SendCEcho()函数中的内容不重要,你可以数到五。当线程死掉时,有一个句柄没有被清除。
对于大多数程序而言,这并不重要,因为它们不会长时间运行。但在我创建的一些程序中,它们需要长时间运行几个月甚至更长时间。
如果你反复执行这段代码,最终可能会泄漏句柄,导致Windows操作系统变得不稳定并无法使用。此时需要重新启动。
我通过使用线程池和类似以下的代码解决了这个问题:
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadJobMoveStudy));
我的问题是为什么.NET会出现这样的泄漏问题,而且它已经存在这么长时间了?自1.0以来一直存在?我在这里找不到答案。
GC.Collect()
并查看句柄数量是否下降吗? - Yacoub MassadSendCEcho
中的循环是无限的。 - Brian Rasmussen