[英]C#, GC didn't call destructor when deleting an object with sub-thread
I'm having a problem in C#, when deleting an object which has a sub-thread running inside, GC doesn't call class destructor even if I add GC.WaitForPendingFinalizers(). 我在C#中遇到问题,删除一个内部运行有子线程的对象时,即使我添加GC.WaitForPendingFinalizers(),GC也不会调用类析构函数。 If I add _TC.Close() manually before _TC = null, destructor will be called properly, what's the reason cause this?
如果我在_TC = null之前手动添加_TC.Close(),则析构函数将被正确调用,这是什么原因引起的?
class Program
{
static void Main(string[] args)
{
TestClass _TC;
_TC = new TestClass();
_TC = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadKey();
}
}
class TestClass
{
Thread _T;
bool _T_KeepWorking = true;
public TestClass()
{
Console.WriteLine("TestClass Created.");
_T = new Thread(new ThreadStart(Test_DoWork));
_T.IsBackground = true;
_T.Start();
}
~TestClass()
{
Close();
Console.WriteLine("TestClass Destroyed.");
}
public void Close()
{
_T_KeepWorking = false;
if (_T.IsAlive)
{
_T.Join();
}
}
public void Test_DoWork()
{
while (_T_KeepWorking)
{
Console.WriteLine("Test_DoWork alived.");
Thread.Sleep(1000);
}
}
As you can read from the comments, most of the time you don't need destructor and your should prefer implementing IDisposable
. 从注释中可以看出,大多数情况下,您不需要析构函数,而您应该更喜欢实现
IDisposable
。 Also lastest versions of the .NET framework introduce Task
: .NET框架的最新版本还引入了
Task
:
static void Main(string[] args)
{
using (var testClass = new TestClass())
{
}
Console.ReadKey();
}
class TestClass : IDisposable
{
private Task _task;
private CancellationTokenSource _cancellationTokenSource;
public TestClass()
{
Console.WriteLine("TestClass Created.");
_cancellationTokenSource = new CancellationTokenSource();
_task = Task.Factory.StartNew(TestDoWork);
}
public void TestDoWork()
{
while (true)
{
if (_cancellationTokenSource.Token.IsCancellationRequested)
{
break;
}
}
Console.WriteLine("Task Ended.");
}
// Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
// Cancel the Task
if (_cancellationTokenSource == null) return;
_cancellationTokenSource.Cancel();
_task.Wait();
_cancellationTokenSource.Dispose();
_cancellationTokenSource = null;
_task = null;
Console.WriteLine("TestClass Dispose.");
}
// free native resources here if there are any
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.