C#网络编程与资源使用

标签 c# .net network-programming using-statement

我一直在研究如何最好地用 C# 编写“正确”的网络代码。

我见过许多使用 C# 的“using”语句的示例,我认为这是一种很好的方法,但是我发现它与各种表达式的用法不一致。

例如,假设我有这样的代码:

TcpClient tcpClient = new TcpClient("url.com", 80);
NetworkStream tcpStream = tcpClient.GetStream();
StreamReader tcpReader = new StreamReader(tcpStream);
StreamWriter tcpWriter = new StreamWriter(tcpStream);

显然,这段代码会非常不稳定。所以,我看到了一些将 using 放在 tcpClient 上的代码,这看起来不错。但是,NetworkStream 不是也有需要清理的资源吗? StreamReader/Writer 呢?

我是否需要将所有 4 个语句包装在嵌套的 using 语句中?

如果是这样,当到了处置的时候会发生什么? StreamWriter 不会关闭流并因此关闭套接字吗?那么,当 StreamReader、NetworkStream、TcpClient 各自完成它们的处置时会发生什么?

这又引出了另一个问题。 StreamReader 和 StreamWriter 由同一个流组成,谁拥有它?难道他们不都认为自己拥有它,因此都会试图摧毁它吗?还是框架知道流已经被销毁而只是静静地忽略它?

似乎 using 语句只对链中的最后一个语句是必需的,但是如果在 GetStream() 中抛出异常会发生什么?我不认为它会在那时正确清理套接字,因此似乎有必要进行冗余使用以确保不会发生这种情况。

有谁知道最近有什么关于使用 .net 进行网络编程的好书,最好是 c#,其中包括关于异常处理和资源管理的章节?或者网上有什么好的文章?我能找到的所有书籍都是 .NET 1.1 时代的(Microsoft .NET Framework 的网络编程、.NET 中的网络编程等),因此这似乎是一个需要一些好的资源的主题。

编辑:

请不要让 Marc 的非常好的评论阻止其他人对此发表评论:)

我想听听其他人对资源管理的书籍推荐或意见,尤其是在异步使用方面。

最佳答案

通常,对象应该在内部处理多个Dispose() 调用,并且只执行一次主要代码;所以流多次获取 Dispose()d 通常不是问题。就个人而言,我会在那里使用大量的 using;请注意,您不需要缩进/嵌套(除非不同级别具有不同的生命周期):

using(TcpClient tcpClient = new TcpClient("url.com", 80))
using(NetworkStream tcpStream = tcpClient.GetStream())
using(StreamReader tcpReader = new StreamReader(tcpStream))
using(StreamWriter tcpWriter = new StreamWriter(tcpStream))
{
   ...
}

如您所说,这可确保如果在初始化期间发生错误,所有内容仍会正确清理。这也确保每个级别都有机会(以正确的顺序)正确处理任何缓冲数据等。

重新拥有; NetworkStream 实际上首先是一个奇怪的地方......大多数流都是或者 输入xor 输出。 NetworkStream 改变了一些规则并将两个方向填充到一个 API 中;所以这是一个异常(exception)......通常所有权会更清楚。此外,许多包装器都有一个标志来确定它们是否应该关闭包装的流。 StreamReader 没有,但有些有(例如 GZipStream,它有一个 leaveOpen ctor 选项)。如果您不想流动所有权,这是一个选项 - 或者使用非关闭流中介 - 一个是 here (NonClosingStream 或类似的)。

再读;我拿起了一份“C# 中的 TCP/IP 套接字:程序员实用指南”( here ) - 足够,但不是很好。

关于C#网络编程与资源使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/500551/

相关文章:

c++ - WinAPI NetUserGetInfo() 因 Active Directory 域上的 NERR_UserNotFound 错误代码而失败

.net - ASP.NET 5 平台和 MVC 6 有什么区别

c# - 寻找最佳实践 : Communication between 2 Applications for Filebrowsing and Download

c++ - 验证 IP 地址已发布的简单方法

c# - 不可变的集合?

javascript - 如何在 WebStorm 中调试 .NET 嵌入式 js 文件?

c - 有没有办法设置套接字选项来指示数据包转到哪个接口(interface)

c# - Create View后返回的ViewModel为空

c# - 如何评论为什么可以忽略捕获

javascript - 在 TextChanged 或 CheckedChanged 事件上使用 JavaScript 清除两个 TextBox 和 checkBox