繁体   English   中英

C#网络编程和资源使用

[英]C# network programming and resource usage

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

我已经看过使用C#的“using”语句的一些例子,我认为这是一个很好的方法,但是我看到它与各种表达式的使用不一致。

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

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

显然,这段代码非常不稳定。 所以,我已经看到一些代码将使用放在tcpClient上,这似乎很好。 但是,NetworkStream是否还有需要清理的资源? 那么StreamReader / Writer呢?

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

如果是这样,当处理时间时会发生什么? 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实际上是摆在首位的古怪......最流或者是输入输出 NetworkStream弯曲一些规则并将两个方向整合到一个API中; 所以这是一个例外...通常所有权会更清楚。 此外,许多包装器都有一个标志来确定它们是否应该关闭包装的流。 StreamReader不会,但有些人会这样做(例如GZipStream ,它有一个leaveOpen ctor选项)。 如果您不想流所有权,这是一个选项 - 或使用非关闭流中介 - 一个在这里NonClosingStream或类似)。

重新上书; 我拿了一份“C#中的TCP / IP套接字:程序员实用指南”( 这里 ) - 足够,但不是很好。

如果一个对象支持IDisposable,最好把它放在using {}块中,因为dispose方法会自动为你调用。 这也减少了您的代码。 重要的是要注意使用'using'不处理任何异常。 如果你想处理任何错误,你仍然必须这样做。 一旦使用块超出范围,您的对象也是如此。

Old Style Code

object obj;

try
{
   obj= new object();
   //Do something with the object
}
catch
{
   //Handle Exception
}
finally
{

  if (obj != null)
  {  
     obj.Dispose();
  }
}  

Newer Style Code

try
{   
  using (object obj = new object())
  {
     //Do something with the object
  }
catch
{
   //Handle Exception
}

套接字怎么样? 可以这样做:

serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Connect(serverEndPoint, m_NegotiationPort);
.
.
.
serverSocket.Close();

或更好

using (Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
.
.
.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM