如果我写
using (Socket s = new Socket(/*...*/))
{
//...
}
结束括号是否调用
s.Shutdown(SocketShutdown.Both);
s.Close();
s.Dispose();
或仅
s.Dispose();
(或其他什么?)
谢谢!
答案 0 :(得分:2)
using语句将调用IDisposable.Dispose
,这就是全部。
using语句只是一个编译器技巧,它允许你更简洁地表达你将总是喜欢处理给定对象,即使块中包含的代码抛出并粗略地转换为以下
Socket s = new Socket(...)
try
{
// Code contained by the using... block here.
}
finally
{
s.Dispose();
}
根据我的经验,using语句很少与Socket
类一起使用。最典型的情况是,您只需拨打内部实际调用Socket.Close
的Socket.Dispose
。
答案 1 :(得分:1)
Close
在.NET的Dispose
类中调用Socket
。 使用块只调用Dispose
。
但这并不意味着使用块无用!
在.NET中,使用块基本上只是 try / finally 的语法糖,其中Dispose
在实现{{1}的对象上被调用}
以下代码:
IDisposable
在编译时扩展为以下代码:
using (var socket = new Socket(/*...*/))
{
// operations
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
您不仅获得了免费的空检查,而且还为{
Socket socket = new Socket(/*...*/);
try
{
// operations
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
finally
{
if (socket != null)
((IDisposable)socket).Dispose();
}
}
类的实例创建了额外的范围。
最终,我建议在这种情况下使用 using block ,因为它确保在异常的情况下在Socket
类的实例上调用Dispose
被抛出等等。
在这种情况下,使用使用块时,我可以想到很多东西并且几乎没有什么可失去的。另一方面,当我不使用使用块时,我会想到很多东西会丢失。
答案 2 :(得分:0)
如果您查看ILSpy或Reflector.NET中的Socket代码,您将看到以下代码:
public void Close()
{
if (Socket.s_LoggingEnabled)
{
Logging.Enter(Logging.Sockets, this, "Close", null);
}
((IDisposable)this).Dispose();
if (Socket.s_LoggingEnabled)
{
Logging.Exit(Logging.Sockets, this, "Close", null);
}
}
基本上调用Dispose()
是多余的。拨打Close()
即可。