【发布时间】:2010-11-06 11:23:53
【问题描述】:
【问题讨论】:
-
(请参阅我对您的评论的回答的更新)
标签: c# multithreading
【问题讨论】:
标签: c# multithreading
如果你需要暂停一个线程,让它调用Sleep。
如果您需要它暂停直到某个条件变为真,请使用条件变量或等待。
.NET 中的条件变量使用Monitor 方法,包括Wait 和Pulse; see here 进行介绍。 (Windows Vista 还向 Win32 API 添加了本机条件变量支持,但这是一个完全独立的实现,.NET 从 V1.0 开始支持条件变量)。
对于等待:即蚂蚁使用 WaitAny 或 WaitAny 方法重载 WaitHandle 类来等待在 .NET 中作为 WaitHandle 子类公开的各种 Win32 同步对象类型之一(事件,互斥体、可等待计时器等)。
【讨论】:
一般来说,不要暂停(或中止)Thread - 您通常无法知道它在做什么,这可能会导致各种锁定问题,例如未释放的 a 锁,或挂起的类型初始化程序(静态构造函数)。
但是,您可以通过更优雅的方法暂停代码 - 例如,在循环中使用 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...
}
然后另一个具有访问权限的线程(可能是间接的)可以暂停 (Reset) 并恢复 (Set) 工作线程,但知道它只会在安全状态下暂停。
关于您的评论(在另一条回复中)- 听起来您有读者和作者;非常适合生产者/消费者场景。我有一个示例on this question,说明如何编写具有上限大小的生产者/消费者(因此,如果消费者运行缓慢,它就不会淹没) - 如果没有数据,消费者会阻塞,如果有数据,生产者会阻塞太多了。
【讨论】:
ManualResetEvent来控制线程的状态,但是当我在VirtualBox托管的Windows XP中测试这个机制时,它失败了。
如果您想这样做,即使这是一个坏主意,请查看 Suspend 和 Resume 方法 - MSDN 有关于此主题的 more info,包括为什么这是一个坏主意。
重复一遍 - 我强烈建议您改用 Marc Gravell 的解决方案。
【讨论】:
如果您中止了线程,它将无法再次运行。您可以在不同的线程上运行相同的任务(例如相同的ThreadStart 委托),但这不会再次运行相同的线程。
我会强烈建议您不要硬中止线程,除非您的应用程序出现故障。相反,请制定一个graceful thread termination 协议,这样您就可以告诉任务您希望它停止。 “暂停”线程也是如此——你真的不想在线程持有一些关键资源时暂停它。
也许如果您能告诉我们更多关于您的情况,我们可以提供更多帮助。使用monitors(参见页面后半部分)或wait handles,可以轻松实现优雅的暂停/恢复或取消功能。
【讨论】: