知道ThreadPool何时为空

时间:2012-02-25 05:34:15

标签: c# multithreading backgroundworker threadpool

我似乎无法找到一种简单的方法来确定ThreadPool何时完成所有排队任务。我在这里找到了一些答案,但没有一个可以帮助我。

为简单起见,我们说:

for (int i=0;i<10;i++)
{
   threadpool.queueuserworkitem(Go);

}
void Go()
{
   Console.WriteLine("Hello");
}

那么在所有10个后台线程完成后,我怎样才能发送最终的“All done”console.writeline?

由于

3 个答案:

答案 0 :(得分:3)

你不会问线程池,而是你会得到每个后台线程来提供它何时完成的通知。

但是不要自己做那个管道,使用新的TPL和Task类:

var tasks = new Task[10];
for (int i=0;i<10;i++)
{
    tasks[i] = Task.Factory.StartNew( Go );
}

Task.WaitAll(tasks);
Console.WriteLine("All done");

void Go()
{
   Console.WriteLine("Hello");
}

编辑: 我想问为什么你想要完成10个线程来完成工作。默认任务计划程序已针对检测到的CPU核心数进行了优化。但是如果必须,还有一个TaskScheduler的实现,它将并发度限制为固定数量: http://msdn.microsoft.com/en-us/library/ee789351.aspx

答案 1 :(得分:1)

您是否尝试过使用Reactive Extensions

Rx这样做非常简单。例如,您可以像这样重写您的问题:

    private void test()
    {
        var list = Enumerable.Range(0, 10)
            .ToObservable()
            .ObserveOn(Scheduler.ThreadPool)
            .SubscribeOn(Scheduler.ThreadPool)
            .Subscribe(i=>Go(),Done);

    }

    void Go()
    {
        Console.WriteLine("Hello");
    }

    void Done()
    {
        Console.WriteLine("Done");
    }

超级简单。看看Rx,你会很高兴

答案 2 :(得分:0)

依赖线程池空虚是不可能和危险的。你能做的就是自己计算你的活动任务。监视器的低级方法:

   class Program
    {
        static object _ActiveWorkersLock = new object();
        static int _CountOfActiveWorkers;

        static void Go(object state)
        {
            try
            {
                Console.WriteLine("Hello");
            }
            finally
            {
                lock (_ActiveWorkersLock)
                {
                    --_CountOfActiveWorkers;
                    Monitor.PulseAll(_ActiveWorkersLock);
                }
            }
        }

        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                lock (_ActiveWorkersLock)
                    ++_CountOfActiveWorkers;
                ThreadPool.QueueUserWorkItem(Go);
            }

            lock (_ActiveWorkersLock)
            {
                while (_CountOfActiveWorkers > 0)
                    Monitor.Wait(_ActiveWorkersLock);
            }

            Console.WriteLine("All done");
        }
    }