Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 忙着在C等待#_C#_Multithreading_Concurrency - Fatal编程技术网

C# 忙着在C等待#

C# 忙着在C等待#,c#,multithreading,concurrency,C#,Multithreading,Concurrency,如何以一种不完全低效的方式实现忙等待?我面临的问题是,我只能以拉方式加载模型的数据,这意味着我必须以连续的方式调用getXYZ()方法 这对于用户交互来说速度不够快,但是足够快,当GUI中的状态发生变化时,可以注意到模型,并通过getXYZ()方法接收新的状态 我的做法是: while (c.hasChanged()) { Thread.sleep(500); } updateData(); 有更好的机制吗?从您的帖子中不清楚您到底想做什么,但听起来您应该将模型/服务调用放在一个单独的线

如何以一种不完全低效的方式实现忙等待?我面临的问题是,我只能以拉方式加载模型的数据,这意味着我必须以连续的方式调用getXYZ()方法

这对于用户交互来说速度不够快,但是足够快,当GUI中的状态发生变化时,可以注意到模型,并通过getXYZ()方法接收新的状态

我的做法是:

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

有更好的机制吗?

从您的帖子中不清楚您到底想做什么,但听起来您应该将模型/服务调用放在一个单独的线程上(通过后台工作程序或异步委托),并使用来自模型/服务调用的回调在完成时通知UI。你的UI线程可以做一些繁忙的事情,比如显示进度条,但不会变得没有响应。

你的问题似乎可以用它来解决

在WPF中,您可以执行以下操作:

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

}).Start();
以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();
可能缺少参数(在调用UI线程上执行代码所需的参数),但我是从大脑中编写的,因此没有智能感知可供使用:D

在.NET4中,您可以使用它,而不是自己生成线程。
在.Net中,如果从GUI进行轮询,请使用(WinForms)计时器


如果这是某种背景过程,那么你的Sleep()可能不是那么糟糕

明确的忙碌等待是邪恶的,必须尽可能避免

如果无法避免,则使用Observer设计模式构建应用程序,并将感兴趣的对象注册到执行轮询的对象,该对象由线程支持


这样你就有了一个干净的设计,把丑陋的东西限制在一个地方。

查看后台线程(BackgroundWorker或裸线程)请说明什么样的应用程序正在轮询模型。据我所知,除了最琐碎的程序外,不应使用VOLATILE。它不仅在AMD和安腾处理器上都不安全。约瑟夫·阿尔巴哈里(Joseph Albahari)还为英特尔处理器编写了一个简单的测试代码,证明volatile在这里也不安全-@John我同意你的看法,但由于这个特殊的volatile布尔值将在循环中读取,因此如果读取错误一两次,其实并不重要(不管这是因为缓存一致性还是其他原因,在某个时候它都会被重新读取)。错误的是如果编译器将while(bClosing)替换为while(true).我不是框架专家,但从文档摘录中可以看出,编译器永远不会对易失性变量进行优化。无论如何,最好的方法是将其作为一个属性。
while (!Closing)