如何启动一个已停止的线程

14

我从主线程创建一个新的线程并启动它。

m_MyThread = new Thread(HandleMyThread);
m_MyThread.IsBackground = true;
m_MyThread.Start();

private void HandleMyThread()
{
    while (true)
    {
        Thread.Sleep(5000);
        return;
    }
}

5秒后,该线程将会结束,并且其ThreadState状态为Stopped。我希望在用户点击按钮时再次启动它,但是我遇到了一个ThreadStateException(线程正在运行或已终止;无法重新启动)

private void button1_Click(object sender, EventArgs e)
{
    m_MyThread.Start(); // ->raise exception
}
请帮我了解如何重新启动已停止的线程。谢谢。

1
有关停止线程的更多信息,请参考我的问题: 正确的停止线程作业的方法 - Gerard
@Leovo,请看一下这个链接:https://learn.microsoft.com/zh-cn/dotnet/standard/threading/pausing-and-resuming-threads#interrupting-threads,虽然不是答案,但可能会有所帮助。 - antonio
4个回答

16

我知道这个问题有点老了,但是我认为我应该回复一下,以防别人来到这里没有答案。

对于这个示例代码,如果它被更改为以下内容:

Thread m_MyThread;
private void HandleMyThread()
{
    while (true)
    {
        Thread.Sleep(5000);
        return;
    }
}

private void button1_Click(object sender, EventArgs e)
{
    if (!m_MyThread.IsAlive)
    {
        m_MyThread = new Thread(HandleMyThread);
        m_MyThread.IsBackground = true;
        m_MyThread.Start();
    }
}

这将创建一个新的线程实例并启动它。出现ThreadStateException错误是因为,简单地说,您不能重新启动处于停止状态的线程。对于处于未启动状态的线程,m_MyThread.Start()是有效的。在这种情况下需要做的是创建一个新的线程实例并在新实例上调用Start()


1
我知道这个答案有点老了,但它仍然解决了我的问题。 - DudeWhoWantsToLearn

3

使用ManualResetEvent,而不是Thread.Sleep,等待带有超时的事件。

然后,任何其他线程都可以激活该事件,并立即恢复正在休眠的线程。

一旦线程退出,它就无法再运行。因此,请勿让它退出。相反,将其放回睡眠状态,等待事件发生。


我在我的应用程序中遇到了一个问题。当我运行我的应用程序时,我需要创建一个线程,它会睡眠到下一个早上8点钟,然后触发一个事件。请告诉我如何解决这个问题。目前,我创建了一个线程,并计算从现在到早上8点的总毫秒数,以便它可以睡眠这段时间。睡眠结束后,它将触发一个事件。你对我的方法有什么建议吗?谢谢。 - Leo Vo

2

只需像初始创建线程时一样创建新线程即可。您可能还希望将其提取到方法中以避免重复。


2
如果您想在不每次创建新线程的情况下重复使用线程,您可以考虑实现线程池。

但是在两种方式中,哪种是最好的呢,因为我想重复使用线程。请告诉我两种方式的优缺点。 - Leo Vo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接