简体   繁体   English

与套接字一起使用块

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM