3

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 !

  • You'll have a better chance of getting the answer if you provide language tag :) – zero323 Oct 16 '13 at 20:21
  • 1
    I have to disagree. The using block is not redundant. What happens to the instance of Socket class when an Exception is thrown, etc.? – Derek W Oct 16 '13 at 21:00
  • @Derek I forgot the Exceptions... –  Oct 16 '13 at 21:16
  • I can think of no drawbacks of using the **using block** (although I know some programmers who find it aesthetically unappealing), but I can think of a few when not using it. – Derek W Oct 16 '13 at 21:36

3 Answers3

3

The using statement will call IDisposable.Dispose and that is all.

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

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. Most typically you would only call the Socket.Close which will actually call Socket.Dispose internally.

User 12345678
  • 7,714
  • 2
  • 28
  • 46
2

Close calls Dispose in the Socket class in .NET. The using block just calls Dispose.

But this doesn't mean that the using block is useless!

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. 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.

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.

I can think of much to gain and literally nothing to lose when using a using block in this case. On the other hand, I can think of much to lose when not using the using block.

Derek W
  • 9,708
  • 5
  • 58
  • 67
  • The documentation for [`Socket.Dispose`](http://msdn.microsoft.com/en-us/library/cc190731.aspx) does not support this. Whilst `Socket.Close` _"Closes the Socket connection **and** releases all associated resources."_, `Socket.Dispose` _"Releases all resources used by the current instance of the Socket class."_ – User 12345678 Oct 16 '13 at 20:44
  • @ByteBlast: You link to Socket.Close. And what does it not support? – Derek W Oct 16 '13 at 20:46
  • The documentation does not support that _"`Close` and `Dispose` do the same thing in the `Socket` class"_. – User 12345678 Oct 16 '13 at 20:49
  • Releasing a socket closes it. However it may not be a clean shutdown, you do need to call the `Shutdown` method for that (but note that after an exception, you're probably not getting a clean shutdown anyway) – Ben Voigt Oct 16 '13 at 21:13
  • BTW the edit is wrong. The documentation does not say that `Close` calls `Dispose`. `Close` closes the socket and prepares the socket wrapper instance to be reused. `Dispose` closes the socket and does not prepare for reuse. In fact, the .NET 4.5 implementation of `Dispose` does everything `Close` is documented to do, and `Close` calls it. But this is not guaranteed in other versions. – Ben Voigt Oct 16 '13 at 21:16
  • @BenVoigt: But what about .NET Reflector: http://stackoverflow.com/a/3601548/1608786 – Derek W Oct 16 '13 at 21:23
  • So as it turns out, `Close` leaves the socket in a non-reusable state, and `ObjectDisposedException` will be thrown thereafter. – Ben Voigt Oct 16 '13 at 21:27
0

If you look at the code of Socket in ILSpy or Reflector.NET you will see the following code:

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. Calling Close() is enough.

bleepzter
  • 9,607
  • 11
  • 41
  • 64