2012-03-07 27 views
8

我有一个方法void DoWork(object input)需要大约5秒钟才能完成。我已经阅读ThreadThreadPool更适合这些较长的操作,但我遇到了问题。主题:如何在线程完成后重新启动?

我点击一个按钮,它调用threadRun.Start(input)它运行并完成罚款。我再次点击按钮,收到以下异常:

Thread is running or terminated; it cannot restart.

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

+0

我刚刚查了我的一些代码,每次我重新创建线程我需要重用它。我这样做是因为我的代码中也出现了完全相同的错误。在我的情况下,这样做并不昂贵,所以我没有进一步调查。 – ChrisF 2012-03-07 22:41:48

+0

对于螺纹VS线程池检查此[计算器帖] [1] [1]:http://stackoverflow.com/questions/230003/thread-vs-threadpool – 2012-03-07 22:45:51

回答

10

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

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

我应该使用线程池?

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

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

想象一下,服务于大量快速操作的线程池。你不想有太多的线程,因为电脑一次只能做很多事情。每一个你做线程池的长操作都会连接池中的一个线程。所以池必须有很多额外的线程或可能缺少线程。两者都不会导致高效的线程池设计。

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

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

我假设你的意思是使用专用于作业的线程,然后终止使用线程池。优点是线程数将始终等于这种方式的作业数量。这意味着每次开始工作时都必须创建一个线程,并且每次完成一个线程时都销毁一个线程,但是您永远不会有额外的线程,也不会在线程中出现短缺。 (这可能是与我的好事/ O绑定线程,但可以是一件坏事,如果多数线程是CPU密集型的大部分时间。)

+0

很大的反响!感谢您花时间回答我的许多问题。 :) – john 2012-03-08 15:22:35

1

由于消息状态,您无法重新启动线程。您可以简单地为您的下一个操作创建一个新线程。或者,您可能会考虑设计后台线程继续工作,直到完成所有任务,而不是为每个任务启动一个新线程。

1

它在设计上看起来像这样。

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

一个搜索现在已经变成了this thread on social.msdn那里接受的答案状态:

停止或中止线程不能再次陈述。

MSDN重复这个问题,以及:

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

0

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

1

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

3

Thread.Start文件说:

一旦线程终止,它不能与其他呼叫 重新启动。

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

相关问题