[英]using block with Socket
If I write 如果我写
using (Socket s = new Socket(/*...*/))
{
//...
}
Does the closing brace call 右括号是否响起
s.Shutdown(SocketShutdown.Both);
s.Close();
s.Dispose();
Or only 或仅
s.Dispose();
? ?
(Or something else ?) (或者是其他东西 ?)
Thank you ! 谢谢 !
The using statement will call IDisposable.Dispose
and that is all. using语句将调用IDisposable.Dispose
,仅此IDisposable.Dispose
。
The using statement is simply a compiler trick that allows you to more concisely express that you would always like to dispose of the given object even if the code contained by the block throws and roughly translates into the following using语句只是一个编译器技巧,使您可以更简洁地表达出,即使该块所包含的代码抛出并大致转换为以下内容,您也总是希望处置给定的对象
Socket s = new Socket(...)
try
{
// Code contained by the using... block here.
}
finally
{
s.Dispose();
}
In my experience the using statement is seldomly used in conjunction with the Socket
class. 以我的经验,using语句很少与Socket
类结合使用。 Most typically you would only call the Socket.Close
which will actually call Socket.Dispose
internally. 最典型的情况是,您只会调用Socket.Close
,而后者实际上会在内部调用Socket.Dispose
。
Close
calls Dispose
in the Socket
class in .NET. Close
调用在.NET中的Socket
类中Dispose
。 The using block just calls Dispose
. using块仅调用Dispose
。
But this doesn't mean that the using block is useless! 但这并不意味着using块是无用的!
In .NET, using blocks are essentially just syntactic sugar for a try/finally where Dispose
is called on the object implementing the IDisposable
interface in the using statement . 在.NET中, using块本质上只是尝试/最后的语法糖,其中在using语句中在实现IDisposable
接口的对象上调用Dispose
。 There are some differences as I illustrate and explain below. 我在下面说明和解释了一些区别。
The following code: 如下代码:
using (var socket = new Socket(/*...*/))
{
// operations
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
Expands to the following code at compile time: 在编译时扩展为以下代码:
{
Socket socket = new Socket(/*...*/);
try
{
// operations
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
finally
{
if (socket != null)
((IDisposable)socket).Dispose();
}
}
Not only are you getting a free null-check, but you're also creating an extra scope for your instance of Socket
class. 您不仅可以获得免费的空检查,而且还为Socket
类的实例创建了一个额外的作用域。
Ultimately, I would recommend using the using block in this case since it ensures that Dispose
is called on the instance of the Socket
class in the case of an exception being thrown, etc. 最终,我建议在这种情况下使用using块 ,因为这样可以确保在抛出异常等情况下,在Socket
类的实例上调用Dispose
。
I can think of much to gain and literally nothing to lose when using a using block in this case. 我可以想到在这种情况下使用using块会获得很多收益,而实际上没有损失。 On the other hand, I can think of much to lose when not using the using block . 另一方面,当不使用using块时,我会想到很多损失。
If you look at the code of Socket in ILSpy or Reflector.NET you will see the following code: 如果您查看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);
}
}
Essentially calling Dispose()
is redundant. 本质上,调用Dispose()
是多余的。 Calling Close()
is enough. 调用Close()
就足够了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.