是否可以从拥有对象的Dispose方法中停止线程?
本文关键字:方法 线程 Dispose 拥有 对象 是否 | 更新日期: 2023-09-27 18:02:20
下面是一个简单的例子:
class MyClass : IDisposable
{
bool working;
public MyClass()
{
working = true;
Thread t = new Thread(Worker);
t.Start();
}
void Worker()
{
while(working)
{}
}
public void Dispose()
{
working = false;
}
}
这样做可以吗?Dispose()会在线程还在运行的时候被调用吗?如果没有,如何更好地做到这一点?
Dispose
将不会被调用,除非你显式地调用它,或者通过在using
语句中包含MyClass
实例化。
将处置()甚至被调用,而线程仍在运行?
可以这样调用:
using (MyClass m = new MyClass())
{
System.Threading.Thread.Sleep(2000);
}
因此,一旦using
块结束,它将调用类中的Dispose
方法。
(尽管您的变量应该是volatile
,以表明该字段可能被多个线程修改)
但重要的是要注意,Dispose
没有什么神奇的东西,甚至using
语句也转换成try-finally
,其中Dispose
在finally
块中显式调用。
你不应该依赖于你的Dispose
方法将被调用。
你可以用WeakReference
包装你的类实例。一旦引用被垃圾收集,线程应该停止它的工作。
class MyClass : IDisposable
{
class CancellationSignal
{
WeakReference _reference;
public bool IsWorking { get { return _working && _reference.IsAlive; } }
volatile bool _working;
public CancellationSignal(WeakReference reference)
{
if (reference == null) throw new ArgumentNullException("reference");
_reference = reference;
}
public void Signal()
{
_working = false;
}
}
CancellationSignal _cancellationSignal;
public MyClass()
{
_cancellationSignal = new CancellationSignal(new WeakReference(this));
Thread t = new Thread(Worker);
t.Start(_cancellationSignal);
}
static void Worker(object state)
{
var s = (CancellationSignal)state;
while (s.IsWorking)
{
//...
}
}
public void Dispose()
{
_cancellationSignal.Signal();
}
}
我个人更喜欢避免使用终结器,但我仍然不得不说,另一个解决方案是在终结器中调用Signal
(然后你可以删除WeakReference
的东西):
~MyClass()
{
_cancellationSignal.Signal();
}
注意_working
被声明为volatile。您也可以使用ManualResetEventSlim
甚至CancellationToken
来代替。
在这两种方法(WeakReference
和终结器),你必须避免传递this
引用到线程(因为它会防止你的类实例被垃圾收集),因此我添加了一个CancellationSignal
类,并将Worker
标记为静态