【发布时间】:2010-11-08 21:43:46
【问题描述】:
我有一个正在使用的第三方组件,但我发现一些资源未释放的问题。该组件使 Windows 创建 UDP 套接字(“\Device\Udp”以及“\Device\Afd”)的句柄。如果我允许程序执行和取消引用第三方对象,我假设像我过去使用过的所有 .NET 对象一样,该对象将被垃圾收集。但是,Process Explorer 显示“\Device\Udp”句柄被无限期保留,直到实际进程被终止(或者在有问题的应用程序的情况下:应用程序池被回收。
此外,如果我手动调用对象的 Dispose() 方法,则释放句柄。这是我已经解决的问题,但我只是好奇为什么需要它。是否有可能组件的构建者做了一些事情或设置了一些属性来阻止垃圾收集器调用对象的破坏?
如果有帮助,我在下面发布了代码。该代码已在 Forms 应用程序中使用,因此该过程不会在 while 循环完成后结束。
不起作用的代码(无限期创建 100 个句柄):
for (int i = 0; i < n; i++)
{
Snmpmgr mgr = new Snmpmgr();
mgr.Timeout = 10;
mgr.ObjCount = 1;
mgr.ObjId[1] = ".1.3.6.1.2.1.1.1.0";
try
{
mgr.SendGetRequest(); // Handle shows up in ProcExplorer after this call
}
catch (Exception ex)
{
throw new TimeoutException("Error contacting CMTS.");
}
} // end of for... obj referenced by mgr never garbage collected
有效的代码(创建和发布的句柄):
for (int i = 0; i < n; i++)
{
Snmpmgr mgr = new Snmpmgr();
mgr.Timeout = 10;
mgr.ObjCount = 1;
mgr.ObjId[1] = ".1.3.6.1.2.1.1.1.0";
try
{
mgr.SendGetRequest(); // Handle shows up in ProcExplorer after this
}
catch (Exception ex)
{
throw new TimeoutException("Error contacting CMTS.");
}
mgr.Dispose(); // UDP Socket Handle freed... not sure that's how to spell free + ed :)
}
提前感谢您的帮助。
克里斯
【问题讨论】:
-
您能否实际展示一段代码片段,说明您是如何在
Snmpmgr类中创建套接字句柄的? -
Snmpmgr 是 nsoftware 制作的第三方组件:nsoftware.com/portal/dotnet。对于我们支付的价格标签,我真的不想对第三方软件进行故障排除。我主要是好奇他们组件的行为是否有问题,所以我可以打开一个案例。
-
如下所述,正确的答案是在完成对象后自己 Dispose() 。也就是说,听起来供应商没有正确实施处置模式(参见msdn.microsoft.com/en-us/library/fs2xkftw%28VS.80%29.aspx 和stackoverflow.com/questions/898828/c-finalize-dispose-pattern)。简而言之,如果你有一个类有需要释放的非托管资源,如果 Dispose() 还没有被确定性地调用,你应该在垃圾收集期间自己释放它们。
标签: .net sockets garbage-collection udp