2012-01-06 3 views
1

Скажем, у меня есть следующий код:Располагая TcpClient при наличии ссылки на NetworkStream

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); 
} 

Когда я компилирую это, анализ кода говорит мне, что я должен распоряжаться tcpClient до ссылки выходит за рамки. Проблема в том, что мне нужно использовать экземпляр базового потока дальше, и я не могу распоряжаться tcpClient здесь. Одновременно я не хочу хранить ссылку на tcpClient где-нибудь, чтобы позже распоряжаться, поскольку мне нужен только поток. Какое правильное решение здесь? Благодарю.

+2

, что это проблема с сохранением ссылки на 'tcpClient'? – Yahia

+0

теперь вы хотите вернуть SSLStream или Client, если это изменит возврат в моем примере и подписи метода. – MethodMan

+0

@Yahia Предполагается, что существует множество экземпляров «Клиент». Однако для класса 'Client' нужен только экземпляр' Stream' только в качестве параметра, и я хочу оставить его независимым от класса 'TcpClient'. – eigenein

ответ

1
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; 
     } 
    } 
} 
0

вы можете сделать это двумя способами .. 1. передать вар по реф или 2. объявить приватную переменную в верхней части как SslStream sslStream = NULL; есть этот

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

изменить его или метод, чтобы прочитать в следующем.

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 
} 
+0

Нет проблем с 'SslStream' специально. Проблема заключается в том, что 'tcpClient' должен быть удален, а основной поток - нет. – eigenein

+0

Да, но когда вы распоряжаетесь tcpClient, вы возвращаете SSLStream, теперь GAC может ударить, возможно, однажды, когда переменная sslStream выходит за пределы области видимости, но я полагаю, что вы используете этот sslStream после обратного вызова. Имеет ли это смысл..? – MethodMan

+0

'Клиент' принимает экземпляр' Stream' и использует его. – eigenein

Смежные вопросы