C# 线程:完成后如何重新启动线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9610226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Thread: How to re-start thread once completed?
提问by john
I have a method void DoWork(object input)that takes roughly 5 seconds to complete. I have read that Threadis better suited than ThreadPoolfor these longer operations but I have encountered a problem.
我有一个void DoWork(object input)大约需要 5 秒才能完成的方法。我读过它Thread比ThreadPool这些更长的操作更适合,但我遇到了一个问题。
I click a button which calls threadRun.Start(input)which runs and completes fine. I click the button again and receive the following exception:
我单击一个按钮,threadRun.Start(input)该按钮调用该按钮可以正常运行并完成。我再次单击该按钮并收到以下异常:
Thread is running or terminated; it cannot restart.
Thread is running or terminated; it cannot restart.
Can you not "reuse" a Thread? Should I use ThreadPool? Why is Thread "better suited for longer operations" compared to ThreadPool? If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
你不能“重用”一个线程吗?我应该使用线程池吗?与 ThreadPool 相比,为什么 Thread“更适合更长的操作”?如果你不能重用一个线程,为什么要使用它(即它提供了什么优势)?
采纳答案by David Schwartz
Can you not "reuse" a Thread?
你不能“重用”一个线程吗?
You can. But you have to code the thread not to terminate but to instead wait for more work. That's what a thread pool does.
你可以。但是您必须对线程进行编码而不是终止,而是等待更多工作。这就是线程池所做的。
Should I use ThreadPool?
我应该使用线程池吗?
If you want to re-use a thread, yes.
如果你想重复使用一个线程,是的。
Why is Thread "better suited for longer operations" compared to ThreadPool?
与 ThreadPool 相比,为什么 Thread“更适合更长的操作”?
Imagine a thread pool that is serving a large number of quick operations. You don't want to have too many threads, because the computer can only do so many things at a time. Each long operation you make the thread pool do ties up a thread from the pool. So the pool either has to have lots of extra threads or may run short of threads. Neither leads to an efficient thread pool design.
想象一个线程池,它服务于大量的快速操作。你不想有太多线程,因为计算机一次只能做这么多事情。您使线程池执行的每个长操作都会从池中占用一个线程。因此,池要么必须有很多额外的线程,要么可能会缺少线程。两者都不会导致高效的线程池设计。
For longer operations, the overhead of creating and destroying a thread is very small in comparison to the cost of the operation. So the normal downside of using a thread just for the operation doesn't apply.
对于较长的操作,与操作成本相比,创建和销毁线程的开销非常小。因此,将线程仅用于操作的正常缺点并不适用。
If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
如果你不能重用一个线程,为什么要使用它(即它提供了什么优势)?
I'm assuming you mean using a thread dedicated to a job that then terminates over using a thread pool. The advantage is that the number of threads will always equal the number of jobs this way. This means you have to create a thread every time you start a job and destroy a thread every time you finish one, but you never have extra threads nor do you ever run short on threads. (This can be a good thing with I/O bound threads but can be a bad thing if most threads are CPU bound most of the time.)
我假设您的意思是使用专用于作业的线程,然后使用线程池终止。这样做的好处是线程数将始终等于作业数。这意味着您必须在每次开始工作时创建一个线程并在每次完成时销毁一个线程,但您永远不会有额外的线程,也永远不会出现线程短缺。(这对于 I/O 绑定线程来说可能是一件好事,但如果大多数线程在大多数时间都是 CPU 绑定的,则可能是一件坏事。)
回答by Jon B
As the message states, you cannot restart the thread. You can simply create a new thread for your next operation. Or, you might consider a design where the background thread keeps working until it completes all of your tasks, rather than launch a new thread for each one.
正如消息所述,您无法重新启动线程。您可以简单地为下一个操作创建一个新线程。或者,您可以考虑这样一种设计,即后台线程一直工作直到完成所有任务,而不是为每个任务启动一个新线程。
回答by ChrisF
It looks like this by by design.
它的设计看起来像这样。
I encountered the same problem and the only solution I could find was to recreate the thread. In my case I wasn't restarting the thread very often so I didn't look any further.
我遇到了同样的问题,我能找到的唯一解决方案是重新创建线程。就我而言,我并没有经常重新启动线程,所以我没有再看下去。
A search now has turned up this thread on social.msdnwhere the accepted answer states:
现在搜索已在 social.msdn 上找到此线程,其中已接受的答案指出:
a stopped or aborted thread cannot be stated again.
停止或中止的线程不能再次声明。
The MSDNrepeat this as well:
在MSDN重复这个问题,以及:
trying to restart an aborted thread by calling Start on a thread that has terminated throws a ThreadStateException.
尝试通过在已终止的线程上调用 Start 来重新启动已中止的线程会引发ThreadStateException。
回答by Tim P.
It's just in background mode. It sounds like you need to use the ThreadPool because re-starting and re-creating Thread objects are very expensive operations. If you have a long running job that may last longer than your main process, then consider the use of a Windows Service.
它只是在后台模式。听起来您需要使用 ThreadPool,因为重新启动和重新创建 Thread 对象是非常昂贵的操作。如果您有一个长时间运行的作业,其持续时间可能比您的主进程更长,那么请考虑使用 Windows 服务。
回答by Martin James
for(;;){}or while(true){}are useful constructs to 'reuse' a thread. Typically, the thread waits on some synchronization object at the top of these loops. In your example, you could wait on an event or semaphore and signal it from your button OnClick()handler.
for(;;){}或者while(true){}是“重用”线程的有用构造。通常,线程在这些循环的顶部等待某个同步对象。在您的示例中,您可以等待事件或信号量并从按钮OnClick()处理程序中发出信号。
回答by GETah
Thread.Startdocumentation says:
Thread.Start文档说:
Once the thread terminates, it cannot be restarted with another call to Start.
一旦线程终止,就不能通过另一个对 Start 的调用来重新启动。
Threads are not reusable. I have already faced this problem a while ago, the solution was to create a new Threadinstance whenever needed.
线程不可重用。不久前我已经遇到了这个问题,解决方案是Thread在需要时创建一个新实例。

