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

.net 什么';确定线程已停止的最佳方法是什么?,.net,multithreading,verification,.net,Multithreading,Verification,我有一个Windows服务,它有许多线程,这些线程都需要在服务停止之前停止。我使用此模型停止线程并发出它们已停止的信号: ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { Thread1Running = true; try { while (running) { AutoReset1.WaitOne(TimeSpan.FromSeconds(30.0

我有一个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,并在所有的autoreset上调用set()。这会立即向线程发出停止睡眠的信号,或者在线程处理完正在处理的内容后立即停止。这真的很有效。但是,我最紧张的部分是验证一切都停止了。这就是我现在正在做的:

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

    Thread.Sleep(TimeSpan.FromSeconds(5.0));
}
Int32尝试=0;
而(尝试<5&(线程1运行| | |线程2运行| |线程3运行))
{
尝试++;
线程睡眠(TimeSpan.FromSeconds(5.0));
}

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


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

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


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

我认为执行此操作的一般方法是在线程上加入。调用的细节将取决于您正在使用的线程库,但一般来说,
join
方法将一直阻止,直到线程退出(如果线程已经死了,应该立即返回)。因此,您可以按顺序加入所有线程,然后退出。如果所有联接都已返回,则所有线程都已退出


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

请注意。在调用Join之前,您应该添加对RequestAdditionalTime的调用,否则SCM将从他的示例代码中关闭您,很明显,他的线程库是.net
System.threading
namespace.Thread.Join是一种更好的方法。从功能上来说,它和我做的一样,但是它更干净。它仍然受到时间的限制,但我可以接受。你知道我如何将它与线程池一起使用吗?或者我必须实际生成线程吗?实际上,我希望线程池上应该有一个方法,您可以使用它来阻止线程,直到它的线程关闭为止。至少我已经习惯(java)了。哦,Join实际上有点不同,至少和我记忆中的不同。它更干净,因为它允许做一些额外的清理。至少从我处理它时的记忆来看(在.Net中可能与GC之类的有所不同。我回想起我的C时代)。在调用Join之前,您应该添加对RequestAdditionalTime的调用,否则SCM将从他的示例代码中关闭您,很明显,他的线程库是.net
System.threading
namespace.Thread.Join是一种更好的方法。从功能上来说,它和我做的一样,但是它更干净。它仍然受到时间的限制,但我可以接受。你知道我如何将它与线程池一起使用吗?或者我必须实际生成线程吗?实际上,我希望线程池上应该有一个方法,您可以使用它来阻止线程,直到它的线程关闭为止。至少我已经习惯(java)了。哦,Join实际上有点不同,至少和我记忆中的不同。它更干净,因为它允许做一些额外的清理。至少从我处理它时的记忆来看(在.Net中可能与GC等不同。我回想我的C时代)。您使用的是什么.Net版本?3.5但4.0可能是一个选项。您使用的是什么.Net版本?3.5但4.0可能是一个选项。