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

时间:2012-11-27 17:53:25

标签: c# multithreading abort

假设我将这两个方法排在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);
    });
}

有没有办法阻止输出Console.WriteLine("Output2");的所有线程,但保持那些输出Console.WriteLine("Output");的线程?

2 个答案:

答案 0 :(得分:15)

您可以使用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();

答案 1 :(得分:2)

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

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

对项目进行排队后,您可以设置标记以告知其余项目不执行:

   lock(syncObject)
   {
        shouldOutput2 = false;
   }

这是一种非常肮脏的方式,但它似乎是给出你的例子的唯一方法。如果您能告诉我们更多关于您想要实现的实际行为的信息,那么可能会有更好的选择。