2 .net c# design-patterns idisposable
您如何看待以下IDisposable模式实现?
public class Connection : IDisposable
{
private Socket _socket;
public bool IsConnected()
{
if (_socket.Poll(1, SelectMode.SelectRead) && _socket.Available == 0)
return false;
return true;
}
public void Disconnect()
{
if (m_socket != null && IsConnected())
{
try
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Disconnect(false);
}
catch (SocketException se)
{
System.Console.WriteLine(se.Message);
}
}
}
~Connection()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!IsConnected())
{
if (disposing)
{
Disconnect();
}
else
{
AppDomain currentDomain = AppDomain.CurrentDomain;
if (currentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted)
{
System.Console.WriteLine("Client failed to call Destroy");
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我使用上面的代码给出了这个错误:
{"尝试对不是套接字的操作进行操作"} System.Net.Sockets.Socket.Poll(Int32 microSeconds,SelectMode模式)
cas*_*One 11
实施存在严重缺陷.你没有真正实现IDisposable,你最终依靠垃圾收集器来清理你的资源,这是一件坏事.
此外,当GC确实出现时,你甚至都没有正确地清理这些资源(它确实正确地执行了,但错误的是它发生了).
IDisposable当您持有实现的引用时,您的类负责实现IDisposable.然后,在你的实现中Dispose,如果你没有被GCed(它是一个显式的调用Dispose),你将调用你正在持有的Dispose任何IDisposable实现.
您检查了连接状态Socket,但这与调用Dispose它不同,并且您因此泄漏了资源(GC最终将其取出).
有关如何正确实现的准则IDisposable,请参阅位于此处的MSDN文档"实现完成并部署以清理非托管资源"部分:
http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx
我应该注意到,我不完全同意这些指导方针,但它们是最常用的.对于我的立场,请看这里:
http://www.caspershouse.com/post/A-Better-Implementation-Pattern-for-IDisposable.aspx