线程:如何在完成后重新启动线程?

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

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

Thread is running or terminated; it cannot restart.

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

你能否“重用”一个线程?

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

我应该使用ThreadPool吗?

如果你想重用一个post,是的。

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

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

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

如果你不能重用一个线程,为什么要使用它(即它提供了什么优势)?

我假设您的意思是使用专用于作业的线程,然后使用线程池终止。 优点是线程数总是等于这种方式的作业数。 这意味着你必须在每次启动一个作业时创建一个线程并在每次完成一个线程时销毁一个线程,但是你从来没有额外的线程,也没有在线程上做空。 (对于I / O绑定线程,这可能是一件好事,但如果大多数线程在大多数情况下都是CPU绑定的话,这可能是一件坏事。)

Thread.Start文档说:

线程终止后,无法通过另一次调用Start重新启动。

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

它看起来像是设计的。

我遇到了同样的问题,我能找到的唯一解决方案是重新创建线程。 在我的情况下,我没有经常重新启动线程所以我没有再看了。

搜索现在已经在social.msdn上找到了这个主题,接受的答案是:

停止或中止的线程无法再次声明。

MSDN也重复这个:

试图通过在已终止的线程上调用Start来重新启动已中止的线程抛出一个ThreadStateException

如消息所示,您无法重新启动该线程。 您只需为下一个操作创建一个新线程即可。 或者,您可以考虑后台线程继续工作的设计,直到完成所有任务,而不是为每个任务启动新线程。

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

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