c# - 取消 ThreadPool .QueueUserWorkItem 任务

标签 c# threadpool cancellation

我需要取消使用 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 (在循环内)

关于c# - 取消 ThreadPool .QueueUserWorkItem 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7731610/

相关文章:

elasticsearch - 为什么当线程池和队列已满时,elasticsearch 会拒绝几乎所有查询,而不是尽可能多地回答并拒绝剩余的查询?

http - 已取消请求的正确 HTTP 状态代码是什么

c# - 如何在序列中找到未知的重复子序列?包括子序列的递归搜索

c# - 使用泛型方法时如何正确约束相关类类型?

python - 在 Python 中选择正确的线程数

c# - 如何取消自定义等待

exception-handling - 如何在不抛出 TaskCanceledExceptions 的情况下等待任务?

c# - 插入数据并用新数据刷新数据网格后关闭弹出窗口

c# - 了解线程以及与 .NET 和 WPF 的同步

java - Tomcat线程池?在tomcat.conf中被注释掉了,我应该使用它吗?