确定线程已停止的最佳方法是什么?

时间:2010-09-29 17:09:56

标签: .net multithreading verification

我有一个Windows服务,它有许多线程,在服务停止之前都需要停止。我正在使用这个模型来阻止我的线程并发出信号表明它们已被停止:

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
    Thread1Running = true;

    try
    {
        while (running)
        {
            AutoReset1.WaitOne(TimeSpan.FromSeconds(30.0));

            if (running)
            {
                // do stuff
            }
        }
    }
    finally
    {
        Thread1Running = false;
    }
}));

当关闭我的服务停止时,我只是将运行设置为false并在那里的所有AutoResets上调用Set()。这会立即通知线程停止睡眠或在完成处理它们正在处理的内容后停止。这非常有效。但是,我最担心的部分是验证一切都已停止。这就是我现在正在做的事情:

Int32 tries = 0;
while (tries < 5 && (Thread1Running || Thread2Running || Thread3Running))
{
    tries++;

    Thread.Sleep(TimeSpan.FromSeconds(5.0));
}

我不喜欢这个的主要原因是它是基于时间的,如果我的一个线程处于冗长的操作中(很可能),那么关闭可能不会在那25秒内完成(并且非常重要的是,在运行此代码的OnStop时,所有这些线程都会关闭,完成)。我无法删除尝试,因为如果其中一个线程挂起(它们没有,但你永远不知道),那么我真的卡住了,服务永远不会停止。

是否有更好的方法来验证线程是否全部停止,最好是不基于时间的验证?或者我注定要进行一些可能需要更长时间的超时(10次尝试,30秒睡眠,也许)?

1 个答案:

答案 0 :(得分:1)

我相信这样做的一般方法是加入线程。调用的细节取决于您正在使用的线程库,但通常join方法将阻塞,直到线程退出(如果线程已经死亡,则应立即返回)。所以你可以按顺序加入所有线程,然后退出。如果所有联接都已返回,则所有线程都已退出。

许多线程库允许您添加加入超时,您可能希望这样做。这种方式即使您的某个线程挂起您的退出代码也不会阻止。