我需要取消使用 ThreadPool.QueueUserWorkItem(...) 启动的后台任务。我知道BackgroundWorker有专门针对此类事情的构造,但我相信在这种情况下它是矫枉过正的,因为不涉及用户界面。我所说的取消只是指强制完成回调方法。
在我的课程中添加类似以下内容有哪些陷阱?
// Cancellation Property.
private bool _canceled;
public bool CancelTask
{
get { return _canceled; }
set { _canceled = value; }
}
public void DoSomeTask()
{
int iterations = 50;
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCallback), iterations);
}
private void ThreadPoolCallback(object state)
{
if (_canceled)
return; // don't even start.
int iterations = (int)state;
for (int i = 0; !_canceled && i < iterations; i++)
{
//
// do work ...
//
// This allows you to cancel in the middle of an iteration...
if (_canceled)
break;
}
}
有没有更好的办法?
我会使用 CancelTask() 方法而不是属性。要点是调用者应该能够取消任务,但没有人应该能够取消取消任务。
然后,您需要确保 _cancelled 的读取和写入具有适当的内存屏障,否则一个线程可能永远不会观察到另一个线程所做的更改。为此,我将使用 Thread.VolatileWrite (在 CancelTask 内)和 Thread.VolatileRead (在循环内)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)