【问题标题】:C# stop and continueC# 停止并继续
【发布时间】:2010-05-22 04:35:12
【问题描述】:

我需要一些方法在 C# 中有效地执行以下操作:

让程序停止执行直到某个值被改变。

注意:我不想用while循环来避免浪费cpu功率..

编辑: 我希望它在价值发生变化后尽快做出响应..

编辑:这将在我的类方法中,由另一个代码调用,但是要检查的值在我的类中...该方法应该等到其他代码评估并改变我的价值..那么它必须继续做它的工作..不幸的是这已经做了很多次(所以我需要关心性能)

【问题讨论】:

  • 这个应用程序是 Windows 服务吗?您不指定,在交互式(事件驱动)应用程序中暂停执行实际上没有任何意义。
  • 您的要求是矛盾的。您拒绝忙等待是因为它的功耗,并且您要求它尽可能响应,但是忙等待将是尽可能响应。如果您告诉我们您的预算,那就更好了。 “尽可能快”什么也没告诉我们; “在一毫秒内”告诉我们很多。在一毫秒内响应的解决方案可能与响应一微秒或一秒的解决方案大不相同。
  • 停止执行到底是什么意思?是不是你必须在某个时刻中断一些不断运行的线程?你打算如何让它停止?还是更像是您希望在值更改时发生的短暂事件?

标签: c#


【解决方案1】:

【讨论】:

  • 没有Monitor.Set。你是说Monitor.Pulse 还是Monitor.PulseAll
  • 如果您想在没有任何旋转的情况下完全入睡,这就是您要走的路。但是,这要求设置值的代码知道如何在正确的对象上脉冲,否则您的代码将永远不会唤醒。
  • @Stephen,所以使用一个属性,并在调用 set 方法时进行脉冲
【解决方案2】:

如果您正在等待的值设置在同一应用程序的其他位置,您可以使用等待句柄:

AutoResetEvent waitHandle = new AutoResetEvent();
...
//thread will sleep here until waitHandle.Set is called
waitHandle.WaitOne();
...
//this is where the value is set
someVar = someValue;
waitHandle.Set();

(请注意,WaitOne 和 Set 必须发生在不同的线程上,因为 WaitOne 会阻塞调用它的线程)

如果您无权访问更改值的代码,最好的方法是,正如其他人所说,使用循环检查值是否已更改并使用 Thread.Sleep() 以便您'没有使用尽可能多的处理器时间:

while(!valueIsSet)
{
    Thread.Sleep(100);
}

【讨论】:

  • /agree...这是最好的办法
  • 如果目标是阻塞线程,这是最好的方法。要阻塞主线程并阻止任何新输入,直到事件发生,然后将 .WaitOne() 放在主线程中。在另一个线程中,触发唤醒的值,放置 .Set();
【解决方案3】:
while(some-condition-here)
{
    Thread.CurrentThread.Sleep(100); // Release CPU for 100ms
}

我想这叫做旋转睡眠。当然,您可以将 100 调整为您认为合适的任何值。基本上就是每次检查的超时时间。

还有其他方法可以做到这一点,但这是最简单的,而且效率很高。

这本电子书实际上引用了它:

Threading in C# by Joseph Albahari: Part 2: Basic Synchronization

【讨论】:

  • 我以前用过这个,但我不喜欢它。 (所以我不会修改你的答案。)我总是“闻起来”不对。
  • @Pretzel 我参考了一本谈论它的书(电子书)。
  • 仅仅因为它在书中并不能使它正确。此外,引用作者的话,“也许它最大的用途是当程序员放弃让更复杂的信号构造工作时!”
  • @Aren B:嘿,我不会敲门的。我偶尔会使用它,但我总觉得我的代码使用它有点“脏”。像马特乔丹一样,我也会引用这篇文章:“[睡眠时间延迟] 越大,CPU 效率越高;权衡是延迟增加。任何超过 20 毫秒的开销都可以忽略不计”——只要既然你对这样的延迟没问题,那么我想你没问题。
  • 我想我唯一的其他建议是,如果您在主 GUI 线程中使用这种自旋睡眠技术,请添加: Application.DoEvent() 以便 GUI 保持对事件的响应(又名用户)同时等待条件得到满足——假设你有一个 GUI,那就是......
【解决方案4】:

您可以使用观察者设计模式。它旨在解决像您这样的问题。

这个模式主要包含一个主题和一个观察者。您可以让它快速响应任何变化。

您可以找到更多信息和示例代码here

【讨论】:

  • 如果架构允许(即您可以控制所监控的内容),这可能是一个很好的解决方案。您会得到非常快速的响应,因为您会在更改发生后立即收到事件。主要需要注意的是,您是在执行更改的线程的上下文中执行的,这有时可能会出现问题。
【解决方案5】:
猜你喜欢
  • 2018-08-22
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多