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

时间:2012-03-07 22:37:23

标签: c# multithreading

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

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

Thread is running or terminated; it cannot restart.

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

6 个答案:

答案 0 :(得分:11)

  

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

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

  

我应该使用ThreadPool吗?

如果你想重新使用一个帖子,是的。

  

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

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

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

  

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

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

答案 1 :(得分:5)

Thread.Start文档说:

  

线程终止后,无法通过其他调用重新启动   开始。

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

答案 2 :(得分:2)

按设计看起来像这样。

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

现在搜索已经显示this thread on social.msdn,其中接受的答案表明:

  

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

MSDN重复这一点:

  

尝试通过在已终止的线程上调用Start来重新启动已中止的线程,但会抛出 ThreadStateException

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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