如何在 C# 中中止、暂停和恢复线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1054554/
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
How do I abort, pause and resume threads in C#?
提问by
How do I abort, pause and resume threads in C#?
如何在 C# 中中止、暂停和恢复线程?
Related question:
相关问题:
回答by Marc Gravell
In general, don'tpause (or abort) a Thread
- you can't normally tell what it was doing, and this could lead to all sorts of locking issues, such as an a lock that isn't released, or a type initializer (static constructor) that is left hanging.
一般来说,不要暂停(或中止)a Thread
- 你通常无法判断它在做什么,这可能会导致各种锁定问题,例如未释放的锁或类型初始化程序(静态构造函数) 悬空。
You might, however, pause code through more elegant methods - for example, using a ManualResetEvent
in your loop that external code (on another thread) can open and close:
但是,您可以通过更优雅的方法暂停代码 - 例如,ManualResetEvent
在循环中使用外部代码(在另一个线程上)可以打开和关闭:
// worker loop
while(alive) {
// if the gate is closed, wait up to 5 seconds; if still not
// open, go back to the loop-start to re-check "alive"
if (!gate.WaitOne(5000)) continue;
// do work...
}
Then another thread with access (probably indirect) can pause (Reset
) and resume (Set
) the worker, but in the knowledge that it only pauses in a safe state.
然后另一个具有访问权限的线程(可能是间接的)可以暂停 ( Reset
) 和恢复 ( Set
) 工作线程,但要知道它只会在安全状态下暂停。
Re your comment (on another reply) - it sounds like you have a reader and writer; ideal for a producer/consumer scenario. I have a an example on this questionof how to write a producer/consumer with a capped size (so it won't swamp if the consumer runs slow) - the consumer blocks if there is no data, and the producer blocks if there is too much.
重新评论(在另一个回复中)-听起来您有读者和作者;生产者/消费者场景的理想选择。我有一个关于如何编写具有上限大小的生产者/消费者的示例(因此如果消费者运行缓慢,它不会陷入沼泽) - 如果没有数据,消费者会阻塞,如果有数据,生产者会阻塞太多了。
回答by Jon Skeet
If you've aborted the thread, it won't be able to run again. You could run the same task (e.g. the same ThreadStart
delegate) on a different thread, but that's not running the same threadagain.
如果您已中止线程,它将无法再次运行。您可以ThreadStart
在不同的线程上运行相同的任务(例如相同的委托),但这不会再次运行相同的线程。
I would stronglyadvise you not to hard-abort threads unless your app is coming down. Instead, work out a graceful thread terminationprotocol instead, so you can tell a task that you want it to stop. The same goes for "pausing" a thread - you really don't want to suspend a thread while it's holding some critical resource.
我强烈建议您不要硬中止线程,除非您的应用程序出现故障。取而代之的是制定一个优雅的线程终止协议,这样您就可以告诉任务您希望它停止。“暂停”线程也是如此——你真的不想在线程持有一些关键资源时挂起它。
Perhaps if you could tell us more about your situation, we could help more. Graceful pause/resume or cancel functionality is reasonably easy to achieve with monitors(see the second half of the page) or wait handles.
也许如果你能告诉我们更多关于你的情况,我们可以提供更多帮助。使用监视器(参见页面的后半部分)或等待句柄可以相当容易地实现优雅的暂停/恢复或取消功能。
回答by Rhythmic Fistman
If you need to pause a thread for a while, get it to call Sleep
.
如果你需要暂停一个线程一段时间,让它调用Sleep
.
If you need it to pause until some condition becomes true, use a condition variable or a wait.
如果您需要暂停直到某些条件变为真,请使用条件变量或等待。
For condition variables in .NET use Monitor
methods including Wait
and Pulse
; see herefor an introduction. (Windows Vista also added native Condition Variable support to the Win32 API, but that is a completely separate implementation, .NET has had conditional variable support since V1.0).
对于 .NET 中的条件变量,使用Monitor
包括Wait
和的方法Pulse
;请参阅此处的介绍。(Windows Vista 还为 Win32 API 添加了本机条件变量支持,但这是一个完全独立的实现,.NET 自 V1.0 以来已具有条件变量支持)。
For Waits: that is ant use of WaitAny
or WaitAny
method overloads of the WaitHandle
class to wait on one of the various Win32 synchronisation object types exposed in .NET as subclasses of WaitHandle
(events, mutexes, waitable timers and so forth).
对于等待:即使用类的antWaitAny
或WaitAny
方法重载WaitHandle
以等待在 .NET 中作为子类WaitHandle
(事件、互斥体、可等待计时器等)公开的各种 Win32 同步对象类型之一。
回答by Marcel Popescu
If you want to do it even though it's a bad idea, look at the Suspend and Resume methods - MSDN has more infoon the subject, including why it's a bad idea.
如果您想这样做,即使它是一个坏主意,请查看 Suspend 和 Resume 方法 - MSDN 有关于该主题的更多信息,包括为什么这是一个坏主意。
To repeat - I strongly advise you to go with Marc Gravell's solution instead.
重复一遍 - 我强烈建议您改用 Marc Gravell 的解决方案。