停止 .NET ThreadPool 中的所有线程?

发布于 2024-10-18 07:12:24 字数 117 浏览 7 评论 0原文

我在 .NET 中使用 ThreadPool 在后台发出一些 Web 请求,并且我想要一个“停止”按钮来取消所有线程,即使它们正在发出请求,所以一个简单的 bool 不会执行工作。

我怎样才能做到这一点?

I am using ThreadPool in .NET to make some web request in the background, and I want to have a "Stop" button to cancel all the threads even if they are in the middle of making a request, so a simple bool wont do the job.

How can I do that?

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

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

发布评论

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

评论(3

黑白记忆 2024-10-25 07:12:24

您的情况几乎是 .NET 框架中 取消 模型的规范用例。

这个想法是,您创建一个 CancellationToken 对象并使其可供操作使用您可能想要取消。您的操作偶尔会检查令牌的 IsCancellationRequested 属性,或调用 ThrowIfCancellationRequested

您可以使用 CancellationTokenSource 创建 CancellationToken,并通过它请求取消班级。

这种取消模型与 .NET 任务并行库很好地集成,并且非常轻量级,更重要的是比使用诸如 ManualResetEvent 之类的系统对象(尽管这也是一个完全有效的解决方案)。

Your situation is pretty much the canonical use-case for the Cancellation model in the .NET framework.

The idea is that you create a CancellationToken object and make it available to the operation that you might want to cancel. Your operation occasionally checks the token's IsCancellationRequested property, or calls ThrowIfCancellationRequested.

You can create a CancellationToken, and request cancellation through it, by using the CancellationTokenSource class.

This cancellation model integrates nicely with the .NET Task Parallel Library, and is pretty lightweight, more so than using system objects such as ManualResetEvent (though that is a perfectly valid solution too).

九八野马 2024-10-25 07:12:24

处理这个问题的正确方法是有一个您发出信号的标志对象。

在这些线程中运行的代码需要定期检查该标志以查看它是否应该退出。

例如, ManualResetEvent 对象适合于此。

然后,您可以像这样要求线程退出:

evt.Set();

在线程内部,您可以像这样检查它:

if (evt.WaitOne(0))
    return; // or otherwise exit the thread

其次,由于您正在使用线程池,所以会发生的情况是您排队的所有项目仍将被处理,但是如果将上面的 if 语句添加到线程方法的最开始处,它将立即退出。如果这还不够好,您应该使用普通线程构建自己的系统,这样您就可以完全控制。

哦,只是为了确保,不要使用 Thread.Abort。要求线程正常退出,不要直接杀死它们。

The correct way to handle this is to have a flag object that you signal.

The code running in those threads needs to check that flag periodically to see if it should exit.

For instance, a ManualResetEvent object is suitable for this.

You could then ask the threads to exit like this:

evt.Set();

and inside the threads you would check for it like this:

if (evt.WaitOne(0))
    return; // or otherwise exit the thread

Secondly, since you're using the thread pool, what happens is that all the items you've queued up will still be processed, but if you add the if-statement above to the very start of the thread method, it will exit immediately. If that is not good enough you should build your own system using normal threads, that way you have complete control.

Oh, and just to make sure, do not use Thread.Abort. Ask the threads to exit nicely, do not outright kill them.

猫瑾少女 2024-10-25 07:12:24

如果您要停止/取消另一个线程中的某些处理,ThreadPool 不是最佳选择,您应该使用 Thread 代替,并在容器中管理所有这些(例如全局List),保证您可以完全控制所有线程。

If you are going to stop/cancel something processing in another thread, ThreadPool is not the best choice, you should use Thread instead, and manage all of them in a container(e.g. a global List<Thread>), that guarantees you have full control of all the threads.

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