在 .NET 中重新启动线程(使用 C#)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1054889/
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
Restarting a thread in .NET (using C#)
提问by drowneath
I'm looking for a way to restart a thread that has been stopped by Abort()..
我正在寻找一种方法来重新启动已被 Abort() 停止的线程。
public partial class MyProgram : Form
{
private Thread MyThread = new Thread(MyFunction);
private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button();
public MyProgram()
{
MyThread.Start();
startStopBtn += new EventHandler(doStop);
startStopBtn.Text = "Stop";
}
private static void MyFunction()
{
// do something
}
private void doStop(object sender, EventArgs e)
{
MyThread.Abort();
startStopBtn -= new EventHandler(doStop);
startStopBtn += new EventHandler(doStart);
startStopBtn.Text = "Start";
}
private void doStart(object sender, EventArgs e)
{
MyThread.Start(); // << Error returned when clicking the button for 2nd time
startStopBtn -= new EventHandler(doStart);
startStopBtn += new EventHandler(doStop);
startStopBtn.Text = "Stop";
}
}
Any idea?
任何的想法?
采纳答案by Emiswelt
Simply add MyThread = new Thread(MyFunction) before calling MyThread.Start() in doStart(). Do not create the thread outside of your methods, the space there is thought for declarations.
在 doStart() 中调用 MyThread.Start() 之前,只需添加 MyThread = new Thread(MyFunction)。不要在你的方法之外创建线程,那里的空间是用于声明的。
EDIT: Please note that killing a thread with thread.Abort() can be very dangerous. You should try to accomplish clean multithreading, like Groo described in his post.
编辑:请注意,使用 thread.Abort() 杀死线程可能非常危险。您应该尝试完成干净的多线程,就像 Groo 在他的帖子中描述的那样。
回答by John Saunders
No, there isn't, but why would you want to? Just start up a new thread, with the same ThreadStart, and the same parameter (if any).
不,没有,但你为什么要?只需启动一个具有相同 ThreadStart 和相同参数(如果有)的新线程。
回答by BFree
The simple answer is, you can't. Once a thread has been aborted, you can't restart it. Just create a method or something, that returns a Thread object just how you need it. When you need a new Thread, just get it from that method.
简单的答案是,你不能。一旦线程被中止,就无法重新启动它。只需创建一个方法或其他东西,它就会根据您的需要返回一个 Thread 对象。当您需要一个新线程时,只需从该方法中获取它。
回答by Groo
Once you have aborted your thread, you cannot start it again.
一旦您中止了您的线程,您将无法再次启动它。
But your actual problem is that you are abortingyour thread. You should never use Thread.Abort().
但您的实际问题是您正在中止线程。你永远不应该使用 Thread.Abort()。
If your thread should be paused and continued several times, you should consider using other mechanisms (like AutoResetEvent, for example).
如果您的线程应该暂停并继续多次,您应该考虑使用其他机制(例如AutoResetEvent)。
[EDIT]
[编辑]
The simplest solution to abort a thread, as mentioned by Ian Griffithsin the link above, is:
正如Ian Griffiths在上面的链接中提到的,中止线程的最简单解决方案是:
The approach I always recommend is dead simple. Have a
volatile bool
field that is visible both to your worker thread and your UI thread. If the user clicks cancel, setthis flag. Meanwhile, on your worker thread, testthe flag from time to time. If you see it get set, stop what you're doing.
我一直推荐的方法非常简单。有一个
volatile bool
对您的工作线程和 UI 线程都可见的字段。如果用户单击取消,则设置此标志。同时,在您的工作线程上,不时测试标志。如果你看到它被设置,停止你正在做的事情。
The only thing that you need to do to make it work properly, is to rearrange your background method so that it runs in a loop- so that you can periodically check if your flag has been set by a different thread.
要使其正常工作,您唯一需要做的就是重新安排您的后台方法,使其在循环中运行- 这样您就可以定期检查您的标志是否已由不同的线程设置。
If you need to have pause and resume functionality for the same worker thread, instead of the simple volatile bool
flag approach, you could go for a slightly more complex approach, a synchronizing construct such as AutoResetEvent
. These classes also provide a way to put the worker thread to sleep for a specified (or indefinite) amount of time between signals from the non-worker thread.
如果您需要为同一个工作线程提供暂停和恢复功能,而不是简单的volatile bool
标志方法,您可以采用稍微复杂一些的方法,例如AutoResetEvent
. 这些类还提供了一种方法,可以让工作线程在来自非工作线程的信号之间的指定(或无限期)时间内休眠。
This threadcontains a concrete example with Start, Pause, Resume and Stop methods. Note how Brannon's example neveraborts the thread. It only fires an event, and then waits until the thread finishes gracefully.
该线程包含一个具体示例,其中包含 Start、Pause、Resume 和 Stop 方法。请注意 Brannon 的示例如何从不中止线程。它只触发一个事件,然后等待线程正常完成。
回答by Brad Bruce
If you really need to interrupt the thread function and resume, you should set a condition and then check it periodically during processing.
如果确实需要中断线程函数并恢复,则应该设置一个条件,然后在处理过程中定期检查。
That would allow you to stop processing for some amount of time and then resume.
这将允许您停止处理一段时间然后继续。
I've used events and Wait calls to accomplish a similar task.
我已经使用事件和等待调用来完成类似的任务。
回答by Rhythmic Fistman
The easiest way is to not abort the thread.
最简单的方法是不中止线程。
回答by Sands
I really don't understand why people provide information if they do not know that is correct.. How can a real programmer suspend or stop processing a thread for sometime and then release it and thereby making the code vulnerable... @Brad-- m sorry.. but your idea was not good.. @Rhythmic - You need to work on your way to approach things..
我真的不明白为什么人们在不知道正确的情况下提供信息......一个真正的程序员如何暂停或停止处理线程一段时间然后释放它从而使代码易受攻击...... @Brad--对不起..但你的想法不好..@Rhythmic - 你需要努力处理事情..
BFree was somewhat right if you people got him the same way he wanted to say.. You just need to re-declare that..
如果你们按照他想说的方式得到他的话,BFree 有点对。你只需要重新声明......
below is the example:
下面是示例:
Public Shared Sub ResetAbort()
Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
YourThreadName.Start()
Thread.Sleep(2000)
YourThreadName.Abort()
End Sub
Now you can use this Sub anywhere you want to start the thread. It will automatically abort the thread.
现在您可以在任何想要启动线程的地方使用这个 Sub。它会自动中止线程。
If you want to start the thread on Button1_click() event and stop it on Button2_Click() event use this:
如果要在 Button1_click() 事件上启动线程并在 Button2_Click() 事件上停止它,请使用以下命令:
in Button1_click() event
在 Button1_click() 事件中
Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
YourThreadName.Start()
in Button2_click() event
在 Button2_click() 事件中
YourThreadName.Start()
doing this way you will abort you thread where ever you want and will initialize it again. You can also use YourThreadName.ThreadState.Running property to check if the thread is running or not(Just to avoid multiple instances of the same thread.....
这样做你会在任何你想要的地方中止你的线程并再次初始化它。您还可以使用 YourThreadName.ThreadState.Running 属性来检查线程是否正在运行(只是为了避免同一线程的多个实例......