终止 .NET 线程
我创建了一个运行特定方法的线程。 但有时我想杀死该线程,即使它仍在工作。 我怎样才能做到这一点? 我尝试了 Thread.Abort() 但它显示了一个消息框,显示“线程已中止”。 我应该怎么办?
I have created a thread running a certain method. But sometimes I would like to kill the thread even if it is still working. How can I do this? I tried Thread.Abort() but it shows up a messagebox saying "Thread aborted". What should I do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
不要调用
Thread.Abort()
!Thread.Abort
是危险的。 相反,您应该与线程合作,以便它可以和平地关闭。 需要设计线程,以便可以告诉它自行终止,例如,当您希望线程停止时,可以将布尔keepGoing
标志设置为 false。 然后,线程将具有类似的内容:如果线程可能会在
Sleep
或Wait
中阻塞,那么您可以通过调用Thread.Interrupt()
。 然后线程应该准备好处理 ThreadInterruptedException:Do not call
Thread.Abort()
!Thread.Abort
is dangerous. Instead you should cooperate with the thread so that it can be peacefully shut down. The thread needs to be designed so that it can be told to kill itself, for instance by having a booleankeepGoing
flag that you set to false when you want the thread to stop. The thread would then have something likeIf the thread may block in a
Sleep
orWait
then you can break it out of those functions by callingThread.Interrupt()
. The thread should then be prepared to handle aThreadInterruptedException
:您实际上应该仅将调用 Abort() 作为最后的手段。 您可以使用变量来同步此线程:
这允许您的线程干净地完成它正在做的事情,使您的应用程序处于已知的良好状态。
You should really only call Abort() as a last resort. You can use a variable to sync this thread instead:
This allows your thread to cleanly finish what it was doing, leaving your app in a known good state.
最正确且线程安全的方法是使用 WaitHandle 在线程应该停止时向其发出信号。 我主要使用ManualResetEvent。
在您的线程中,您可以:
其中
this.flag
是 ManualResetEvent 的实例。 这意味着您可以从线程外部调用this.flag.Set()
来停止循环。仅当设置该标志时,WaitOne 方法才会返回 true。 否则,它将在指定的超时(示例中为 100 毫秒)后超时,并且线程将再次运行循环。
The most correct and thread-safe way is to use a WaitHandle to signal to the thread when it's supposed to stop. I mostly use ManualResetEvent.
In your thread, you can have:
where
this.flag
is an instance of ManualResetEvent. This means that you can callthis.flag.Set()
from outside the thread to stop the loop.The WaitOne method will only return true when the flag is set. Otherwise, it will time out after the specified timeout (100 ms in the example) and the thread will run through the loop once more.
杀死一个线程并不是一个好主意。 最好是发出信号,让事情停止,让它优雅地结束。 有多种不同的方法可以做到这一点。
WaitHandle
类发送信号。我不需要重新讨论如何使用每种方法,因为我已经在 这个答案。
It is not a good idea to kill a thread. It is better to signal that it should stop and let it end gracefully. There are various different ways of doing this.
Thread.Interrupt
to poke it if it is blocked.WaitHandle
class to send a signal.There is no need for me to rehash how each method can be used since I have already done so in this answer.
中止线程是一个非常糟糕的主意,因为您无法确定线程在中止时正在做什么。
相反,拥有一个线程可以检查并且外部代码可以设置的属性。 让线程在安全退出时检查此布尔属性。
Aborting a thread is a very bad idea, since you cannot determine what the thread was doing at the time of the abort.
Instead, have a property that the thread can check, and that your external code can set. Let the thread check this boolean property when it's at a safe place to exit.
我同意乔恩·B
I agree to Jon B
我的 WebServer 类中还有杀死线程的示例...
https://net7ntcip .codeplex.com/SourceControl/changeset/view/89621#1752948
我想说,中止是可以的,只需了解后果是什么...只要您在长时间运行的任务之前指示状态,中止将起作用,但标志是必需的,例如(ShouldStop 或 ActionBranch 等)
查看示例!
There are also examples of killing threads in my WebServer class...
https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948
I would say Abort is okay just understand what the ramifications are... as long as you are indicating state before a long running task Abort will work but flags are required such as (ShouldStop or ActionBranch etc)
Check it out for examples!
编辑:
我为此创建了一个小类
注意到它不适用于 async/await
发布了对类的更新,然后 Theodor Zoulias(谢谢:))让我知道这个想法是有缺陷的。
现在我重新发布原始类(不适用于 async/await!)
像这样停止线程:
类:
Edit:
I created a little class for this
Noticed it didn't work with async/await
Posted an update to the class, then Theodor Zoulias (thanks :)) let me know this idea was flawed.
Now I'm reposting the original class (doesn't work with async/await!)
Stop the thread like this:
The class: