句柄只是用來標識應用程序中的不一樣對象和同類中的不一樣的實例的一個數字,一般狀況下,句柄值對普通用戶毫無用處,可是句柄數量卻能夠間接反映出一個程序裏產生的對象實例的多少。句柄數越多,表明程序裏new 出來的對象越多。可是在c#裏,常常會遇到句柄數莫名其妙的增長。c#
DateTime lastTime1 = DateTime.Now.AddHours(1); while (true) { var a = lastTime1 - DateTime.Now; if (a.TotalHours <= 0) { break; } //DoSomething! Thread.Sleep(1000); }
在DoSomeThing裏,若是用一個委託,去更新窗體控件,會發現任務管理器裏的「句柄數」一欄,值會一點點的增長。並且一般都不怎麼降。socket
好比:測試
richTextBox1.Invoke(new EventHandler(delegate { label3.Text ="xxxx"; }));
無論這個匿名委託裏有沒有代碼,句柄數都會增長
可是若是使用上下文同步對象給控件發送消息,這個問題就解決了spa
_syncContext.Post(ReFreshUI, a); private void ReFreshUI(object state) { try { label3.Text = state.ToString(); } catch { } }
並且我還發現一個有意思的問題。
那就是若是在循環裏,添上對 StatusStripLabel控件進行更新的代碼,句柄數也會增長,也是沒有要停的意思。幾分鐘時間裏竟然升到了1000多。若是將這個控件換成Label控件,那麼句柄數會保持不變。這算不算是StatusStripLabel這個控件的bug呢。code
另外,還有一個可能致使句柄數增長的。就是 不少人都會和我同樣,寫上這樣的代碼:對象
socket = new Socket(AddressFamily.InterNetwork, SocketType, SocketType == SocketType.Dgram ? ProtocolType.Udp : ProtocolType.Tcp); IAsyncResult result = socket.BeginConnect(remoteEP, null, null); if (result.AsyncWaitHandle.WaitOne(timeout, false) && socket.Connected) { result.AsyncWaitHandle.Close(); RemoteEndPoint = remoteEP; return true; }
通過測試發現。只要跑一輪這個代碼,句柄數也會增長几個。並且跑完了也不會降下來。後面我想了下,result.AsyncWaitHandle就是一個WaitHandle對象,而咱們知道這個對象是須要顯式地釋放掉才行的。
若是加上 result.AsyncWaitHandle.Close();問題就能夠完美的解決了,句柄數通常都不會上升,甚至可能降一點。blog