使用带有套接字的块
本文关键字:套接字 | 更新日期: 2023-09-27 18:35:36
如果我写
using (Socket s = new Socket(/*...*/))
{
//...
}
是否调用结束大括号
s.Shutdown(SocketShutdown.Both);
s.Close();
s.Dispose();
或仅
s.Dispose();
?
(还是别的什么?
谢谢!
using 语句将调用IDisposable.Dispose
,仅此而已。
using 语句只是一个编译器技巧,它允许您更简洁地表达您总是希望处理给定对象,即使块包含的代码抛出并大致转换为以下内容
Socket s = new Socket(...)
try
{
// Code contained by the using... block here.
}
finally
{
s.Dispose();
}
根据我的经验,use 语句很少与 Socket
类结合使用。大多数情况下,您只会调用实际上将在内部调用Socket.Dispose
的Socket.Close
。
Close
调用 .NET 中Socket
类中的Dispose
。使用块只是调用Dispose
。
但这并不意味着使用块是无用的!
在 .NET 中,使用块本质上只是 try/finally 的语法糖,其中在 using 语句中实现IDisposable
接口的对象上调用Dispose
。下面我将说明和解释,存在一些差异。
以下代码:
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();
}
}
您不仅可以获得免费的 null 检查,还可以为类Socket
实例创建额外的作用域。
最终,我建议在这种情况下使用 using 块,因为它可确保在引发异常等情况下在 Socket
类的实例上调用 Dispose
。
在这种情况下,当使用使用块时,我可以想到很多收获,而实际上没有什么可失去的。另一方面,我可以想到不使用使用块时会损失很多。
如果你在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()
就足够了。