如何正确关闭网络流连接?

4

我有一个应用程序,它正在连接到某些网络服务器(tcp),使用网络流进行连接:

if (!SSL)
{
     _networkStream = new System.Net.Sockets.TcpClient(Server, Port).GetStream();
     _StreamWriter = new System.IO.StreamWriter(_networkStream);
     _StreamReader = new System.IO.StreamReader(_networkStream, Encoding.UTF8);
}

if (SSL)
{
     System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient(Server, Port);
     _networkSsl = new System.Net.Security.SslStream(client.GetStream(), false,
                    new System.Net.Security.RemoteCertificateValidationCallback(Protocol.ValidateServerCertificate), null);
     _networkSsl.AuthenticateAsClient(Server);
     _StreamWriter = new System.IO.StreamWriter(_networkSsl);
     _StreamReader = new System.IO.StreamReader(_networkSsl, Encoding.UTF8);
}

///// since now I working with both reader and writer globally in multiple threads

我正在异步使用读写器(在2个线程中),需要全局可用这两个流(它们在类级别上定义为公共引用),所以我不知道是否可以在此处使用using语句。

如何正确关闭此连接?所有对象(NetworkStream,流写入器和读取器)都有Close()方法。我应该为它们中的所有对象调用它吗?或者只需调用其中一个?是否有必要释放某些资源?

3个回答

2
将它们放入using块中。操作完成后,它将适当地关闭和处理每个流。
using (StreamReader reader = new StreamReader(_networkStream, Encoding.UTF8)) 
{

}

这段代码执行完后,会断开连接吗?还是只会释放读取器? - Petr
@Petr - 你可以嵌套它们,只有在读取器和写入器被处理并且网络流没有可读取的数据时,连接才会关闭。 - Darren
你说“只有在网络流没有数据可读时”,但如果服务器正在向网络流发送一些数据(它有数据可读),但我仍然想强制关闭连接怎么办? - Petr
@Petr 然后您可以使用 .Close() 显式地关闭连接 - 然而,如果在读取过程中强制关闭流,则可能会导致数据被使用。 - Darren

0

当它们被处理时,StreamReaderStreamWriter默认情况下会自动处理底层的NetworkStream。因此,如果您同时使用读取器和写入器,则在尝试关闭第二个时可能会出现“对象已处理”类型的异常。在这种情况下,我更喜欢处理流本身而不是读取器/写入器,因为这样做是没有意义的。

using stream = tcpClient.GetStream();
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
// <use reader and writer>
// <the using statement ensures the stream is disposed of>

如果您坚持要处理读取器和写入器,可以通过 leaveOpen 参数禁用它们的默认自动关闭流行为:

new StreamReader(stream, leaveOpen: true)
new StreamWriter(stream, leaveOpen: true)

如果可能的话,利用using是理想的选择,但实现相同效果的另一种方法是手动调用流的Close()方法或等效地调用其Dispose()方法。


0
使用using() {}块。这样,在使用后所有连接/流都会被正确关闭。
using(_networkStream = new System.Net.Sockets.TcpClient(Server, Port).GetStream())
{
    using(_StreamWriter = new System.IO.StreamWriter(_networkStream))
    {
      //do stuff
    }
    using(_StreamReader = new System.IO.StreamReader(_networkStream, Encoding.UTF8))
    {
       //do stuff
    } 
 }

如果我想异步地使用这个流进行读写,该怎么办?我应该将读取器嵌套到写入器中吗?(读取器在不同的线程中运行) - Petr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接