【问题标题】:What is the best way to make a thread signal another thread in .NET?在 .NET 中使线程向另一个线程发出信号的最佳方法是什么?
【发布时间】:2008-09-22 16:29:54
【问题描述】:

如果用户希望中断执行,我需要另一个线程发出信号,但是我不确定如何实现信号/信号检查机制。我不想在我的项目中使用单例(比如全局 bool),但有替代方案吗?

this thread 中,人们建议在 C++ 中使用适当的结构,但我不知道 .NET 中是否有类似的东西。有人可以解释一下吗?

【问题讨论】:

    标签: .net multithreading signals


    【解决方案1】:

    试试BackgroundWorker。它支持进度更新和取消正在运行的任务。

    如果您希望一个线程等待另一个线程完成它的工作,那么 Monitor.Wait 和 Monitor.Pulse 是不错的选择,ManualResetEvent 也是如此。但是,这些对于取消正在运行的任务实际上并没有任何用处。

    如果你想编写自己的取消代码,你可以在某个地方有一个两个线程都可以访问的字段。将其标记为 volatile,例如:

    private volatile bool cancelling;
    

    让主线程将其设置为 true,并让工作线程定期检查并在完成后将其设置为 false。

    这与拥有一个“全局变量”并没有真正的可比性,因为您仍然可以将信号量变量的范围限制为类的私有。

    【讨论】:

    • 我更喜欢框架解决方案。共享 var 闻起来不像单例吗?感谢您的回答!
    • BackgroundWorker 是框架的一部分(我相信是 2.0)。我同意共享变量是解决问题的方法。
    • 哦,不,我实际上倾向于采用 BW 方法。非框架参考是为了实现我自己的私人地狱:)
    【解决方案2】:

    有点含糊(时间不够),但请查看ManualResetEvent and AutoResetEvent。您可能还想查找 Monitor 和 lock 关键字。

    【讨论】:

    • 这些问题是有人必须坐等他们被设置,或者必须轮询他们被设置。 “主”线程不能坐,我不想要一个繁忙的循环、电池浪费、能源消耗、轮询。
    • 实际上ManualResetEvent或WaitHandle(它的基础)在使用WaitForSingleObject。您的线程将被挂起,直到信号到达。这在上下文切换上浪费了一些周期,并且有大约 100 毫秒的延迟,但在线程发出信号之前不会浪费任何周期。哦:抱歉,我没看到日期。
    【解决方案3】:

    查看 Monitor.Wait 和 Monitor.Pulse。这是一篇关于 .Net 中的线程的优秀文章(非常易读):http://www.albahari.com/threading/part4.aspx

    【讨论】:

    • Monitor.Wait 和 Monitor.Pulse 并不真正适用于取消场景。
    • 这些问题是有人必须坐等他们被设置,或者必须轮询他们被设置。 “主”线程不能坐,我不想要一个繁忙的循环、电池浪费、能源消耗、轮询。
    【解决方案4】:

    一个简单的解决方案,如同步的静态布尔值,应该是您所需要的,而不是一个基于框架的解决方案,这对于您的场景来说是多余的。如果您仍然需要一个框架,请查看parallel extensions to .NET 以获取想法。

    【讨论】:

    • 实际上,调整我的项目以利用 BackgroundWorker 可能会带来更多好处,因为它有一些有用的抽象。但如果它真的很简单,我不会在做一个 volatile bool 之前三思而后行!
    • 但是“主”线程是如何表示发生了某些事情的呢?它不知道已经设置了一个布尔变量。
    • 主线程必须轮询布尔字段,通常在循环中。
    【解决方案5】:

    这取决于您需要什么样的同步。 如果您希望能够在循环中运行线程直到达到某种执行结束 - 您只需要一个静态 bool 变量。 如果您希望一个线程等待另一个线程到达执行点,您可能需要使用 WaitEvents(AutoResetEvent 或 ManualResetEvent)。 如果你需要等待多个 waitHandles,你可以使用 WaitHandle.WaitAll 或 WaitHandle.WaitAny。

    【讨论】:

    • 我已经有一个列表,我可以检查它是否包含超过零个项目。问题是告诉主线程列表中的项目超过零,或者设置了布尔值,或者设置了事件、互斥体或信号音。
    【解决方案6】:

    查看 System.Runtime.Remoting 命名空间。

    【讨论】:

    • ...然后尖叫着逃跑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2016-12-21
    • 2019-02-12
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多