我有课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(使用前将#替换为@)