【问题标题】:Constructor of thread class getting called by mistake线程类的构造函数被错误调用
【发布时间】:2015-02-20 17:22:53
【问题描述】:

我有一个像这样初始化的 ThreadClass

ThreadClass t = new ThreadClass();
Thread thread = new Thread(new ThreadStart(t.Run));
thread.Start();

我的 ThreadClass 有一个析构函数:

~ThreadClass(){ // some stuff }

这个析构函数被“错误地”调用。这意味着线程仍在运行并且工作正常。但是析构函数以不可预知的方式被调用。它并不是真正可重现的,但如果我设置断点并长时间运行我的代码,突然间析构函数被调用。是否有垃圾收集清理我的 ThreadClass。但如果是这样,为什么我的线程继续运行?

【问题讨论】:

  • 你不应该使用析构函数。

标签: .net multithreading destructor


【解决方案1】:

GC 将在最后一个引用超出范围后的某个时间收集一个对象。

如果您的Run() 方法不使用this,则可以随时收集您的实例。 GC.KeepAlive() 可以改变这种行为; 仔细阅读其文档

这就是为什么你不应该将终结器用于清理原生资源之外的任何事情。

【讨论】:

  • 如果你的 Run() 方法不使用这个,你的实例可以随时被收集。我相信这仅适用于作为局部变量保存的实例,而不是对于线程正在执行它的方法的实例(因为线程是根)。这不是这里的情况。我可能错了,如果我错了,请纠正我。
  • @SriramSakthivel:仔细阅读,看起来Thread 实例本身应该通过它的委托来根实例。 referencesource.microsoft.com/#mscorlib/system/threading/…。所以我不确定。
  • 哇!所以你说只保留 ThreadClass 的元素,它们仍然被引用(所有实例变量和函数都被 Run()-Method 使用)。类本身的实例被释放了吗?
  • @StefanVogel:不。字段是this 的成员。如果您使用任何成员,您实际上是在访问this。在推断终结器和对象生命周期之前,您需要了解有关引用和 GC 工作原理的更多信息。
猜你喜欢
  • 2012-11-19
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 2012-07-01
相关资源
最近更新 更多