1

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

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

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

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

当需要关闭我的服务以停止时,我只是将 running 设置为 false 并在所有 AutoResets 上调用 Set()。这会立即向线程发出停止睡眠的信号,或者在它们完成处理他们正在处理的事情后停止。这真的很好用。但是,我最紧张的部分是验证一切都已停止。这就是我现在正在做的事情:

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

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

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

有没有更好的方法来验证线程已经全部停止,最好是不基于时间的?还是我注定要出现某种可能只需要更长的超时时间(也许是 10 次尝试,30 秒的睡眠时间)?

4

1 回答 1

1

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

许多线程库允许您添加超时加入,您可能想要这样做。这样,即使您的一个线程挂起您的退出代码也不会阻塞。

于 2010-09-29T17:18:09.557 回答