2011-02-18 12 views
9

Me preguntaba si alguien sabía la mejor manera de deshacerse de una clase que utiliza un objeto Socket y un objeto NetworkStream. La clase en cuestión tiene una instancia de NetworkStream y una instancia de Socket que se utiliza para crear el NetworkStream.C# - Para cerrar un NetworkStream, la secuencia de llamada.Cerrar o socket.Shutdown?

this.socket = new Socket(
          AddressFamily.InterNetwork, 
          SocketType.Stream, 
          ProtocolType.Tcp) 
         { 
          ReceiveBufferSize = 65536, 
          SendBufferSize = 150 
         }; 

this.socket.Connect(
         new IPEndPoint(                 
           IPAddress.Parse(
              Properties.Settings.Default.MpsServer2), 
              Properties.Settings.Default.MpsPort2)); 

this.stream = new NetworkStream(
         this.socket, true); 

En mi método Dispose, ¿debería hacer esto?

this.stream.Close(); 
this.socket.Shutdown(SocketShutdown.Both); 
this.socket.Close(); 

¿Es todo esto necesario o es excesivo?

Respuesta

2

Socket no dispone de la NetworkStream asociado. Disparé reflector también, estoy seguro. (una herramienta para analizar .NET dlls y thet .NET libraries. Gran herramienta. Tienes que finalizar el mes para descargar la versión gratuita antes de que se complete) comercial.

Sin embargo, según ambos the MDSN documentation y reflector, el flujo cerrará el socket, pero solo si tiene la propiedad del socket. Puede establecerlo como el segundo parámetro en el constructor sobrecargado.

Tiene que llamar a Shutdown en cualquier caso porque si flushes the data. Si no lo hace, podría perder datos.

+0

Voy a marcar esto como la respuesta correcta solo porque tiene más documentación para ello. Me pregunto si el método Dispose de la secuencia podría hacer el trabajo, pero no parece haber mucha información sobre exactamente lo que hará. –

1

Ambos Socket y Stream Implementan IDisposable por lo que puede simplemente llamar al .Dispose() en cada objeto. El método Dispose debe manejar el cierre y otras acciones necesarias para su eliminación.

this.stream.Dispose(); 
this.socket.Dispose(); 

Por ejemplo, este es el desmontado Dispose método de la clase Stream:

public void Dispose() 
{ 
    this.Close(); 
} 
+0

No puede llamar a 'Dispose' en un socket. Solo 'Cerrar'. – Marlon

+1

la implementación de IDisposable de Socket es explícita, lo que significa que no tiene un método de eliminación "público", tendría que convertir Socket a IDisposable para poder invocar a Dispose, p. ((IDisposable) socket) .Dispose() ... – haze4real

+0

usando (var socket = new Socket()) {..} llamará a Dispose() – Hiep

1

De acuerdo con la documentación de MSDN, llamando stream.Close() "Cierra la secuencia actual y libera cualquier recurso (como sockets y manejadores de archivos) asociado con la corriente actual. ", que me dice que stream.Close() también dispone el socket. Aún así, tendrás que llamar a socket.Shutdown().

De todos modos, en mi humilde opinión la forma más segura está utilizando el "uso", que le mantiene en el sitio seguro :)

using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) 
         { 
          ReceiveBufferSize = 65536, 
          SendBufferSize = 150 
         };) { 
    socket.Connect(
    new IPEndPoint(
     IPAddress.Parse(
     Properties.Settings.Default.MpsServer2), Properties.Settings.Default.MpsPort2)); 

    using (var stream = new NetworkStream(socket, true) { 
    // do something with the stream here 
    } 

    socket.Shutdown(SocketShutdown.Both); 
} 
Cuestiones relacionadas