我有這個示例代碼,我試圖找出發生了什麼。使用線程時手柄越來越長 - 爲什麼?
private static AutoResetEvent autoEvent = new AutoResetEvent(false);
private static Thread t1;
static void DoSomething()
{
Console.WriteLine("Main starting.");
ThreadPool.QueueUserWorkItem(
WorkMethod, autoEvent);
// Wait for work method to signal.
autoEvent.WaitOne();
// trying out does resource cleanup by using dispose and null where possible
autoEvent.SafeWaitHandle.Dispose();
t1 = null;
autoEvent = null;
autoEvent = new AutoResetEvent(false);
Console.WriteLine("Work method signaled.\nMain ending.");
}
static Action messageTarget;
static void WorkMethod(object stateInfo)
{
Console.WriteLine("Work starting.");
// This line is going to change
messageTarget = delegate()
{
Thread.Sleep(new Random().Next(100, 2000));
};
// Signal that work is finished.
Console.WriteLine("Work ending.");
((AutoResetEvent)stateInfo).Set();
}
這工作得很好,並在循環100循環(使用TestApi的內存快照的句柄計數)後創建7個句柄。
現在有趣的現象是: 當我換委託在一個線程
t1 = new Thread
(
delegate()
{
Thread.Sleep(new Random().Next(100, 2000));
});
t1.Start();
應用程序完成大約295手柄!
我聽說.net框架與線程和清理資源很差,這是正確的嗎?當應用程序結束時,有可能某些線程仍在後臺運行,但確定這有點極端行爲?
我的問題是如何導致如此高的手數? (請注意,這是模擬的一些行爲在其他應用程序,並不意味着生產,而是要理解爲什麼句柄計數如此大幅度的增長當使用線程)用的Thread.join
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Test.LeakDetection;
namespace FaultDetection
{
public partial class Form1 : Form
{
private Process process;
public Form1()
{
InitializeComponent();
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains("FaultDetection"))
{
//if the process is found to be running then we
//return a true
process = clsProcess;
}
}
MemorySnapshot s1;
if (process != null)
{
s1 = MemorySnapshot.FromProcess(process.Id);
for (int i = 0; i < 100; i++)
{
DoSomething();
MemorySnapshot s2 = MemorySnapshot.FromProcess(process.Id);
// Compare the two memory snapshots and generate a diff.
// Then display the diff to the console.
MemorySnapshot diff = s2.CompareTo(s1);
Console.WriteLine("\tHandle Count: {0}", diff.HandleCount);
label1.Text = "Handle Count: "+ diff.HandleCount + "\n";
}
}
}
private static AutoResetEvent autoEvent = new AutoResetEvent(false);
private static Thread t1;
private static List<Thread> threadReferences;
static void DoSomething()
{
Console.WriteLine("Main starting.");
ThreadPool.QueueUserWorkItem(
WorkMethod, autoEvent);
// Wait for work method to signal.
autoEvent.WaitOne();
t1.Join();
autoEvent.SafeWaitHandle.Dispose();
t1 = null;
autoEvent = null;
autoEvent = new AutoResetEvent(false);
Console.WriteLine("Work method signaled.\nMain ending.");
}
static Action messageTarget;
static void WorkMethod(object stateInfo)
{
Console.WriteLine("Work starting.");
t1 = new Thread
(
delegate()
{
Thread.Sleep(new Random().Next(100, 2000));
});
t1.Start();
//messageTarget = delegate() { Thread.Sleep(new Random().Next(100, 2000)); };
// Signal that work is finished.
Console.WriteLine("Work ending.");
((AutoResetEvent)stateInfo).Set();
}
}
解決方案}
在進行測量之前,請確保所有對象都已正確垃圾收集:'GC.Collect(); GC.WaitForPendingFinalizers();'然後多少個額外的句柄?如果你運行循環1000次,你會得到更多的句柄? –
在40個標記周圍仍然居於頂峯,對於1000個週期,它圍繞着35-40個手柄並保持在那裏 – oliveromahony