析构函数永远不会被调用[重复]

2024-02-09

我有课Class这创造了一个Thread在它的构造函数中。该线程运行一个while(true)循环正在读取非关键数据NetStream。该线程将被析构函数中止:

~Class()
{
 _thread.Abort();
 _thread = null;
}

当程序想要结束使用时Class的实例 -ClassInstance,它调用:

ClassInstance = null;
GC.Collect;

我以为这意味着~Class()届时将自动成为呼叫者 - 但事实并非如此。

该线程即使在之后仍继续运行Application.Exit()并从返回Main().


代码的关键部分不包括在内;线程是如何启动的以及它运行的方法是什么。如果我不得不猜测,我会说你很可能通过传递实例方法来启动线程Class。所以基本上你的类实例仍然以线程的运行为根。您尝试停止终结器中的线程,但终结器将永远不会运行,因为实例仍处于 root 状态,从而导致 catch-22 情况。

另外,您提到该线程正在运行非关键代码,这是您使用的理由Thread.Abort。这实在是一个不够充分的理由。很难控制在哪里ThreadAbortException将被注入到线程中,因此它可能会破坏您没有预料到的关键程序数据结构。

使用新的合作取消 http://msdn.microsoft.com/en-us/library/dd997396.aspxTPL 中包含的机制。改变while (true)循环轮询 a取消令牌 http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.aspx反而。在中发出取消信号Dispose方法当你实现IDisposable。请勿包含终结器(C# 术语中的析构函数)。终结器旨在用于清理非托管资源。由于您没有表明非托管资源正在发挥作用,因此拥有终结器是没有意义的。实现时不必包含终结器IDisposable。事实上,在并不真正需要的情况下拥有它被认为是不好的做法。

public class Class : IDisposable
{
  private Task task;
  private CancellationTokenSource cts = new CancellationTokenSource();

  Class()
  {
    task = new Task(Run, cts.Token, TaskCreationOptions.LongRunning);
    task.Start();
  }

  public void Dispose()
  {
    cts.Cancel();
  }

  private void Run()
  {
    while (!cts.Token.IsCancellationRequested)
    {
      // Your stuff goes here.
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

析构函数永远不会被调用[重复] 的相关文章

随机推荐