在哪里关闭TcpClient成员

时间:2012-03-28 06:56:37

标签: c# tcp destructor idisposable

上下文:我有一个实现“会话”的类,在服务器的生命周期内维持与服务器的TCP连接。在构造函数中,我创建了一个TcpClient实例,其中包含要连接的服务器的给定IP地址和端口。

   public Session(IPAddress ipAddress)
   {
       Client = new TcpClient(ipAddress.ToString(), 1234); //create a client to a server which we will later use to work with
       DataStream = Client.GetStream(); //get the stream for later usage
   }

此会话的对象偶尔会向其关联的服务器发送和接收数据。

我现在的问题是:我应该在哪里关闭TcpClient及其底层NetworkStream?

我应该实现IDisposable吗?但如果我班级的用户忘记调用Dispose会怎样?

我应该实现析构函数(也称为终结器)吗?但AFAIK我永远不应该从那里访问托管资源?

感谢您帮助我!

3 个答案:

答案 0 :(得分:2)

  

我应该实施IDisposable吗?

  

但如果我班级的用户忘记调用Dispose会怎么样?

您应该遵循此处定义的一次性模式:http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx

答案 1 :(得分:1)

查看“When should I Implment IDisposable?

上的无数主题

触发器,因为你有一个实现IDisposable的字段(Client)。因此,您的班级应该是Disposable。

答案 2 :(得分:0)

很少有类应该有清理终结器。如果负责管理IDisposable实例的代码在放弃之前忽略了调用IDisposable.Dispose,则应该修复代码。添加终结器可能会掩盖问题,但无法解决问题,很可能会引入Heisenbugs™。此外,如果一个类负责实现IDisposable并具有终结器的东西,那么该类将需要确保调用那些“Dispose方法”(可能来自它自己的Dispose方法) ,但不负责自己调用那些东西的终结者。实际上,当一个类'终结器正在运行时,对于它所持有引用的任何可终结对象,以下三件事之一通常都是正确的:

  1. 它已经完成了。
  2. 在目前的终结器完成后,它将在队列中尽快完成。
  3. 对它的实时引用将存在于其他地方,并且它不应该被清除。

在任何一种情况下,终结者使用该对象的正确选择是“没有”。