简体   繁体   English

C# 中忙于等待

[英]Busy waiting in C#

How do you implement busy waiting in a not total inefficient way?您如何以一种并非完全低效的方式实现忙碌等待? I am facing the issue that I can load the data of my model only in a pull manner, which means I have to invoke getXYZ() methods in a continuous way.我面临的问题是我只能以拉取方式加载我的 model 的数据,这意味着我必须以连续的方式调用 getXYZ() 方法。

This has to happen not fast enough for user interaction, but fast enought, that when a state in the GUI is changed, the model can be noticed and the new state is received by the getXYZ() methods.对于用户交互来说,这必须发生得不够快,但要足够快,当 GUI 中的 state 发生变化时,可以注意到 model 并且新的 state 方法会收到。

My approach simply be:我的方法很简单:

while (c.hasChanged()) {
   Thread.sleep(500);
}
updateData();

Are there better mechanisms?有没有更好的机制?

Your problem seems to be solvable with Threading .您的问题似乎可以通过Threading解决。

In WPF you can do:在 WPF 你可以这样做:

Thread t = new Thread((ThreadStart)delegate() {
   while (true) {
      Thread.sleep(500);
      if (c.hasChanged())
          Dispatcher.Invoke((Action)delegate() {updateData();});
   }

}).Start();

In WinForms在 WinForms 中

Thread t = new Thread((ThreadStart)delegate() {
   while (true) {
      Thread.sleep(500);
      // this must derive from Control
      if (c.hasChanged())
          this.Invoke((Action)delegate() {updateData();});
   }

}).Start();

There may be missing parameters to Invoke (which is needed to execute the code on the calling UI thread) but I'm writing this from my brain so no intellisense at disposal:D Invoke可能缺少参数(在调用 UI 线程上执行代码所需的参数)但我是从我的大脑中编写的,所以没有智能感知:D

In .NET 4 you can use TaskFactory.StartNew instead of spawning a thread by yourself.在 .NET 4 中,您可以使用TaskFactory.StartNew而不是自己生成线程。 In.Net <= 4, you could use the TreadPool for the thread. In.Net <= 4,您可以将TreadPool用于线程。 However I recall you need this to be run at once because you expect it to be there checking as soon as possible and the thread pool won't assure you that (it could be already full, but not very likely:-).但是我记得您需要立即运行它,因为您希望它尽快在那里检查并且线程池不会向您保证(它可能已经满了,但不太可能:-)。 Just don't do silly things like spawning more of them in a loop!只是不要做一些愚蠢的事情,比如在循环中生成更多它们!

And inside the thread you should put a check like在线程内部,您应该进行检查,例如

while (!Closing)

so that the thread can finish when you need it without having to resort to bad things like t.Abort();这样线程就可以在您需要时完成,而不必求助于t.Abort(); An when exiting put the Closing to true and do a t.Join() to close the checker thread.退出时将 Closing 设置为 true 并执行t.Join()以关闭检查器线程。

EDIT:编辑:

I forgot to say that the Closing should be a bool property or a VOLATILE boolean, not a simple boolean, because you won't be ensured that the thread could ever finish (well it would in case you are closing the application, but it is good practice to make them finish by your will).我忘了说 Closing 应该是 bool 属性或VOLATILE boolean,而不是简单的 boolean,因为您无法确保线程可以完成(如果您关闭应用程序,它会使它们按您的意愿完成的良好做法)。 the volatile keyword is intended to prevent the (pseudo)compiler from applying any optimizations on the code that assume values of variables cannot change volatile 关键字旨在防止(伪)编译器对假定变量值不能更改的代码应用任何优化

It's not clear from your post exactly what you are trying to do, but it sounds like you should put your model/service calls on a separate thread (via Background worker or async delegate) and use a callback from the model/service call to notify the UI when it's done.从您的帖子中不清楚您到底要做什么,但听起来您应该将模型/服务调用放在单独的线程上(通过后台工作人员或异步委托)并使用模型/服务调用中的回调来通知完成后的 UI。 Your UI thread can then do busy things, like show a progress bar, but not become unresponsive.然后,您的 UI 线程可以做一些忙碌的事情,例如显示进度条,但不会变得无响应。

If you are polling from a GUI, use a (WinForms) Timer.如果您从 GUI 轮询,请使用 (WinForms) 计时器。

If this is some kind of background process, your Sleep() may be the lesser evil.如果这是某种后台进程,则您的 Sleep() 可能是较小的邪恶。

Explicit busy waiting is evil and must be avoided whenever possible.显式的忙等待是邪恶的,必须尽可能避免。

If you cannot avoid it, then build your application using the Observer design pattern and register the interested objects to an object which performs the polling, backed by a thread.如果无法避免,则使用观察者设计模式构建应用程序,并将感兴趣的对象注册到执行轮询的 object,由线程支持。

That way you have a clean design, confining the ugly stuff in just one place.这样你就有了一个干净的设计,把丑陋的东西限制在一个地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM