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

发布于 2024-09-25 14:23:36 字数 1032 浏览 6 评论 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;
    }
}));

当需要关闭我的服务以停止时,我只需将运行设置为 false 并在所有 AutoResets 上调用 Set() 。这会立即通知线程停止休眠或在完成处理其正在处理的内容后停止。这确实有效。但是,我最紧张的部分是验证一切都已经停止。这就是我现在正在做的事情:

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

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

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

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

I have a Windows service that has a number of threads that all need to be stopped before the service stops. I'm using this model for stopping my threads and signalling that they have been stopped:

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

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

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

When it comes time to shut my service to stop, I just set running to false and call Set() on all the AutoResets out there. This instantly signals the threads to stop sleeping or to stop once they've finished processing what they're working on. This works really well. But, the part that I'm most nervous about, is verifying that everything has stopped. This is what I'm doing now:

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

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

The main reason that I don't like this is that it's time based, and if one of my threads is in the middle of a lengthy operation (which is quite likely), the shut down may not finish in that 25 seconds (and it's very important that all of these threads be shut down by the time OnStop, where this code gets run, finishes). I can't remove the tries because if one of those threads hangs (they don't, but you never know), then I'm really stuck and the service will never stop.

Is there a better way to do the verification that the threads have all stopped, preferably one that isn't time based? Or am I doomed to having some sort of timeout that might just need to be much longer (10 tries with a 30 second sleep, maybe)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瞳孔里扚悲伤 2024-10-02 14:23:36

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

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

I believe the general method for doing this is to join on the threads. The specifics of the call will depend on the threading library you're using, but in general the join method will block until the thread has exited (and should return immediately if the thread is already dead). So you could just join on all your threads in sequence, then exit. If all your joins have returned then all the threads have exited.

Many threading libraries allow you to add a timeout to join, which you would probably want to do. This way even if one of your threads hangs your exit code doesn't block.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文