句柄只是用来标识应用程序中的不同对象和同类中的不同的实例的一个数字,通常情况下,句柄值对普通用户毫无用处,但是句柄数量却可以间接反映出一个程序里产生的对象实例的多少。句柄数越多,代表程序里new 出来的对象越多。但是在c#里,经常会遇到句柄数莫名其妙的增加。
![](https://www.codeprj.com/image/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvNDQzNjgzLzIwMTUxMS80NDM2ODMtMjAxNTExMDYwNDI5MDkxODAtNDIxNTAxODIyLnBuZw==.png)
DateTime lastTime1 = DateTime.Now.AddHours(1);
while (true)
{
var a = lastTime1 - DateTime.Now;
if (a.TotalHours <= 0)
{
break;
}
//DoSomething!
Thread.Sleep(1000);
}
在DoSomeThing里,如果用一个委托,去更新窗体控件,会发现任务管理器里的“句柄数”一栏,值会一点点的增加。而且通常都不怎么降。
比如:
richTextBox1.Invoke(new EventHandler(delegate
{
label3.Text ="xxxx";
}));
不管这个匿名委托里有没有代码,句柄数都会增加 但是如果使用上下文同步对象给控件发送消息,这个问题就解决了
_syncContext.Post(ReFreshUI, a);
private void ReFreshUI(object state)
{
try
{
label3.Text = state.ToString();
}
catch
{
}
}
而且我还发现一个有意思的问题。 那就是如果在循环里,添上对 StatusStripLabel控件进行更新的代码,句柄数也会增加,也是没有要停的意思。几分钟时间里居然升到了1000多。如果将这个控件换成Label控件,那么句柄数会保持不变。这算不算是StatusStripLabel这个控件的bug呢。
另外,还有一个可能导致句柄数增加的。就是 很多人都会和我一样,写上这样的代码:
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();问题就可以完美的解决了,句柄数一般都不会上升,甚至可能降一点。 |