我一直在研究如何用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()中抛出异常会发生什么?我认为它不会正确地清理套接字,因此似乎需要冗余的using以确保这种情况不会发生。
有没有人知道有关使用.NET和C#进行网络编程并包括有关异常处理和资源管理章节的好书籍或文章?或者在线上有哪些好文章?我能找到的所有书都是.NET 1.1时代的(如《Microsoft .NET Framework网络编程》、《.NET中的网络编程》等),因此这似乎是需要一些好资源的主题。
编辑:
请不要让Marc的很好的评论阻止其他人对此发表评论。
我想听到其他人对资源管理的书籍推荐或意见,特别是关于异步使用。