C# 停止使用 ThreadPool.QueueUserWorkItem 创建的具有特定任务的线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13590154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:06:44  来源:igfitidea点击:

Stop Threads created with ThreadPool.QueueUserWorkItem that have a specific task

c#multithreadingabort

提问by maddo7

Let's say I queue those two methods in a forloop

假设我在for循环中将这两个方法排队

for (int i = 0; i < 100; i++)
{
    ThreadPool.QueueUserWorkItem(s =>
    {
        Console.WriteLine("Output");
        Thread.Sleep(1000);
    });
}

for (int i = 0; i < 100; i++)
{
    ThreadPool.QueueUserWorkItem(s =>
    {
        Console.WriteLine("Output2");
        Thread.Sleep(1000);
    });
}

Is there a way to stop all the threads that output Console.WriteLine("Output2");but keep the ones running that output Console.WriteLine("Output");?

有没有办法停止所有输出的线程Console.WriteLine("Output2");但保持那些运行该输出的线程Console.WriteLine("Output");

采纳答案by jaket

You could use a CancellationToken:

您可以使用 CancellationToken:

for (int i = 0; i < 100; i++)
{
    ThreadPool.QueueUserWorkItem(s =>
    {
        Console.WriteLine("Output");
        Thread.Sleep(1000);
    });
}

CancellationTokenSource cts = new CancellationTokenSource();

for (int i = 0; i < 100; i++)
{
    ThreadPool.QueueUserWorkItem(s =>
    {
        CancellationToken token = (CancellationToken) s;
        if (token.IsCancellationRequested)
            return;
        Console.WriteLine("Output2");
        token.WaitHandle.WaitOne(1000);
    }, cts.Token);
}

cts.Cancel();

回答by Kiril

No, you can't do that. If you want to do something a long the lines then you must write some code to manage it. At the very basic level you need something like this:

不,你不能那样做。如果你想做一些很长的事情,那么你必须编写一些代码来管理它。在最基本的层面上,你需要这样的东西:

object syncObject = new object();
bool shouldOutput2 = true;
ThreadPool.QueueUserWorkItem(s =>
{
    lock(syncObject)
    {
        if(!shouldOutput2)
        {
           return;
        }
    }
    Console.WriteLine("Output2");
    Thread.Sleep(1000);
});

Once you queue the items, then you can set the flag in order to tell the remaining items not to execute:

将项目排队后,您可以设置标志以告诉其余项目不要执行:

   lock(syncObject)
   {
        shouldOutput2 = false;
   }

This is a very dirty way of doing it, but it seems like the only way given your example. If you can tell us more about what is the actual real-world behavior you're trying to accomplish, then there could be some better options.

这是一种非常肮脏的方式,但在您的示例中,这似乎是唯一的方式。如果您能告诉我们更多关于您试图完成的实际现实行为是什么,那么可能会有一些更好的选择。