【问题标题】:How do I abort, pause and resume threads in C#?如何在 C# 中中止、暂停和恢复线程?
【发布时间】:2010-11-06 11:23:53
【问题描述】:

如何在 C# 中中止、暂停和恢复线程?

相关问题:

Is there a way to indefinitely pause a thread?

【问题讨论】:

  • (请参阅我对您的评论的回答的更新)

标签: c# multithreading


【解决方案1】:

如果你需要暂停一个线程,让它调用Sleep

如果您需要它暂停直到某个条件变为真,请使用条件变量或等待。

.NET 中的条件变量使用Monitor 方法,包括WaitPulsesee here 进行介绍。 (Windows Vista 还向 Win32 API 添加了本机条件变量支持,但这是一个完全独立的实现,.NET 从 V1.0 开始支持条件变量)。

对于等待:即蚂蚁使用 WaitAnyWaitAny 方法重载 WaitHandle 类来等待在 .NET 中作为 WaitHandle 子类公开的各种 Win32 同步对象类型之一(事件,互斥体、可等待计时器等)。

【讨论】:

    【解决方案2】:

    一般来说,不要暂停(或中止)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,说明如何编写具有上限大小的生产者/消费者(因此,如果消费者运行缓慢,它就不会淹没) - 如果没有数据,消费者会阻塞,如果有数据,生产者会阻塞太多了。

    【讨论】:

    • 嘿,这是我今天必须给你的第二个 +1,因为我的口头禅之一是:线程应该对自己的生命周期负责,否则你会遇到各种各样的问题,比如死锁和丢失的数据。在这之后,今天不再给你喝汤了:-)
    • 没关系,我现在被封顶了;-p
    • 我试图让一组任务暂停,让我在重新开始之前更新数据表(它们都从同一个数据表中读取)。你知道吗,我可以知道集合中的最后一个任务何时到达数据表的末尾。 ManualResetEvent 是解决我的问题的正确方法吗?感谢您的宝贵时间。
    • 我确实使用ManualResetEvent来控制线程的状态,但是当我在VirtualBox托管的Windows XP中测试这个机制时,它失败了。
    【解决方案3】:

    如果您想这样做,即使这是一个坏主意,请查看 Suspend 和 Resume 方法 - MSDN 有关于此主题的 more info,包括为什么这是一个坏主意。

    重复一遍 - 我强烈建议您改用 Marc Gravell 的解决方案。

    【讨论】:

    • 亲爱的新手,这是一把枪,当我在它的时候,你可以有一些哑弹,小心不要使用这个东西真的很危险:P
    • 嘿,我非常喜欢 Heinlein 的“武装社会就是礼貌社会”的口头禅,所以是的,如果在所有这些警告之后,他想要暂停/恢复……至少我回答了他的问题:)
    【解决方案4】:

    如果您中止了线程,它将无法再次运行。您可以在不同的线程上运行相同的任务(例如相同的ThreadStart 委托),但这不会再次运行相同的线程

    我会强烈建议您不要硬中止线程,除非您的应用程序出现故障。相反,请制定一个graceful thread termination 协议,这样您就可以告诉任务您希望它停止。 “暂停”线程也是如此——你真的不想在线程持有一些关键资源时暂停它。

    也许如果您能告诉我们更多关于您的情况,我们可以提供更多帮助。使用monitors(参见页面后半部分)或wait handles,可以轻松实现优雅的暂停/恢复或取消功能。

    【讨论】:

    • 我在此提议禁止 Jon Skeet 和 Marc Gravell... 在前 30 分钟内禁止回答复杂问题,并且永远禁止回答简单问题:P
    • 我的应用程序通过连续线程从 rfid 阅读器读取并将标签的 id 数据写入数据库,在该标签上写入数据时我想中止或暂停该线程并恢复它以及如何暂停特定线程请帮助我在这方面
    猜你喜欢
    • 2011-08-08
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多