【问题标题】:Thread: How to re-start thread once completed?线程:线程完成后如何重新启动线程?
【发布时间】:2012-03-25 11:56:00
【问题描述】:

我有一个方法 void DoWork(object input) 大约需要 5 秒才能完成。我读到ThreadThreadPool 更适合这些更长的操作,但我遇到了问题。

我单击一个调用threadRun.Start(input) 的按钮,该按钮运行并完成正常。我再次单击该按钮并收到以下异常:

Thread is running or terminated; it cannot restart.

你不能“重用”一个线程吗?我应该使用线程池吗?与 ThreadPool 相比,为什么 Thread “更适合更长的操作”?如果您不能重用线程,为什么还要使用它(即它提供了哪些优势)?

【问题讨论】:

  • 我刚刚检查了我的一些代码,每次需要重用它时我都会重新创建线程。我这样做是因为我的代码中也出现了完全相同的错误。就我而言,这样做并不太贵,所以我没有进一步调查。
  • 对于线程与线程池,请检查此 [stackoverflow 帖子][1] [1]:stackoverflow.com/questions/230003/thread-vs-threadpool

标签: c# multithreading


【解决方案1】:

你不能“重用”一个线程吗?

你可以。但是您必须对线程进行编码而不是终止,而是等待更多的工作。这就是线程池的作用。

我应该使用线程池吗?

如果你想重复使用一个线程,是的。

与 ThreadPool 相比,为什么 Thread “更适合更长的操作”?

想象一个为大量快速操作提供服务的线程池。你不希望有太多线程,因为计算机一次只能做这么多事情。您使线程池执行的每个长操作都会占用池中的一个线程。因此,池要么必须有很多额外的线程,要么可能会缺少线程。两者都不会导致高效的线程池设计。

对于较长的操作,与操作成本相比,创建和销毁线程的开销非常小。因此,仅将线程用于操作的正常缺点并不适用。

如果您不能重用线程,为什么还要使用它(即它提供了哪些优势)?

我假设您的意思是使用专用于作业的线程,然后使用线程池终止。这样做的好处是线程的数量总是等于作业的数量。这意味着您必须在每次开始工作时创建一个线程,并在每次完成一个工作时销毁一个线程,但是您永远不会有额外的线程,也不会出现线程不足的情况。 (这对于 I/O 绑定线程可能是一件好事,但如果大多数线程大部分时间都受 CPU 绑定,则可能是一件坏事。)

【讨论】:

  • 很好的回应!感谢您花时间回答我的众多问题。 :)
【解决方案2】:

Thread.Start 文档说:

一旦线程终止,它就不能被另一个调用重新启动 开始。

线程不可重用。不久前我已经遇到过这个问题,解决方案是在需要时创建一个新的Thread 实例。

【讨论】:

    【解决方案3】:

    它的设计是这样的。

    我遇到了同样的问题,我能找到的唯一解决方案是重新创建线程。就我而言,我并没有经常重新启动线程,所以我没有进一步查看。

    现在搜索出现了this thread on social.msdn,其中接受的答案是:

    已停止或中止的线程不能再次声明。

    MSDN 也重复这个:

    尝试通过在已终止的线程上调用 Start 来重新启动已中止的线程会引发 ThreadStateException

    【讨论】:

      【解决方案4】:

      如消息所述,您无法重新启动线程。您可以简单地为您的下一个操作创建一个新线程。或者,您可以考虑这样一种设计,即后台线程一直工作直到完成所有任务,而不是为每个任务启动一个新线程。

      【讨论】:

        【解决方案5】:

        for(;;){}while(true){} 是“重用”线程的有用构造。通常,线程在这些循环的顶部等待某个同步对象。在您的示例中,您可以等待一个事件或信号量并从您的按钮 OnClick() 处理程序发出信号。

        【讨论】:

          【解决方案6】:

          它只是处于后台模式。听起来您需要使用 ThreadPool,因为重新启动和重新创建 Thread 对象是非常昂贵的操作。如果您有一个长时间运行的作业可能比您的主进程持续更长时间,那么请考虑使用 Windows 服务。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多