eigenein
eigenein

Reputation: 2200

Disposing TcpClient when having a reference to NetworkStream

Say I have the following code:

public static Client Connect(string hostname, int port, bool useSsl)
{
    TcpClient tcpClient = new TcpClient(hostname, port);
    if (!useSsl)
    {
        return new Client(tcpClient.GetStream());
    }
    SslStream sslStream = new SslStream(tcpClient.GetStream());
    sslStream.AuthenticateAsClient(hostname);
    return new Client(sslStream);
}

When I compile this, Code Analysis says me that I should dispose tcpClient before the reference is out of scope. The problem is that I need to use the underlying stream instance further and I can't dispose the tcpClient here. Simultaneously, I don't want to store a reference to the tcpClient somewhere in order to dispose later as I need the stream only. What is the right solution here? Thanks.

Upvotes: 1

Views: 2142

Answers (2)

Matthew
Matthew

Reputation: 25763

public class Client : IDisposable
{
    private TcpClient tcpClient = null;

    public Client(string hostname, int port, bool useSsl) // c'tor
    {
        tcpClient = new TcpClient(hostname, port);

        if (!useSsl)
        {
            Init(tcpClient.GetStream());
            return;
        }

        SslStream sslStream = new SslStream(tcpClient.GetStream());
        sslStream.AuthenticateAsClient(hostname);

        Init(sslStream);            
    }

    private void Init(Stream stream)
    {
        // bla bla bla
    }

    public void Dispose()
    {  
        // this implementation of Dispose is potentially faulty (it is for illustrative purposes only)
        // http://msdn.microsoft.com/en-us/library/ms244737%28v=vs.80%29.aspx

        if( tcpClient != null ) {
            tcpClient.Close();
            tcpClient = null;
        }
    }
}

Upvotes: 1

MethodMan
MethodMan

Reputation: 18843

you can accomplish this in two ways.. 1. pass the var by ref or 2. declare a private variable at the top as SslStream sslStream = null; have this

SslStream sslStream = new SslStream(tcpClient.GetStream()); 

change it or the method to read as the following.

public static SSLStream Connect(ref string hostname, ref int port, bool useSsl) 
{     
   TcpClient tcpClient = new TcpClient(hostname, port);
   if (!useSsl) 
   {
      return new Client(tcpClient.GetStream());
   }
   sslStream = new SslStream(tcpClient.GetStream()); // or the ref sslStream 
   sslStream.AuthenticateAsClient(hostname);
   tcpClient = null; or if implements IDisposable then do this
   if (tcpClient != null)
   {
      ((IDisposable)tcpClient).Dispose();
   }
   return sslStream; //if yo
} 

Upvotes: 0

Related Questions