取消 ThreadPool .QueueUserWorkItem 任务

发布于 2024-12-09 20:09:23 字数 859 浏览 1 评论 0原文

我需要取消使用 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;
    }
}

有更好的办法吗?

I need to cancel a background task started using ThreadPool.QueueUserWorkItem(...). I know a BackgroundWorker has constructs especially for this sort of thing, but I believe it's overkill in this case, since no user interface is involved. By cancellation, I simply mean force the completion of the callback method.

What are the pitfalls of adding something like the following to my class?

// 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;
    }
}

Is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷…雨湿花 2024-12-16 20:09:23

我会使用 CancelTask​​() 方法而不是属性。要点是调用者应该能够取消任务,但没有人应该能够取消取消任务。

然后,您需要确保 _cancelled 的读取和写入具有适当的内存屏障,否则一个线程可能永远不会观察到另一个线程所做的更改。为此,我将使用 Thread.VolatileWrite (在 CancelTask​​ 内)和 Thread.VolatileRead (在循环内)

I'd use a method CancelTask() rather than a property. The point is that callers should be able to cancel a task, but no one should be able to un-cancel a task.

Then you need to be sure that the read and the write of _cancelled have the appropriate memory barriers otherwise one thread might not ever observe the change made by the other thread. For this I'd use Thread.VolatileWrite (inside CancelTask) and Thread.VolatileRead (inside your loop)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文