你如何以一种不是完全低效的方式实现忙碌等待?我面临的问题是,我只能以拉入的方式加载模型的数据,这意味着我必须以连续的方式调用getXYZ()方法。
对于用户交互,这必须发生得不够快,但是足够快,当图形用户界面中的状态改变时,模型可以被注意到,并且getXYZ()方法接收新的状态。
我的方法很简单:
while (c.hasChanged()) {
Thread.sleep(500);
}
updateData();
有没有更好的机制?
发布于 2011-04-30 07:02:36
您的问题似乎可以用Threading解决。
在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();
可能缺少Invoke的参数(在调用UI线程上执行代码时需要它),但是我是从我的大脑中编写的,所以没有智能感知
在.NET 4中,您可以使用TaskFactory.StartNew而不是自己创建线程。在.Net <= 4中,您可以使用线程的TreadPool。然而,我记得你需要立即运行它,因为你希望它尽快在那里检查,而线程池不能保证这一点(它可能已经满了,但不太可能:-)。只是不要做一些愚蠢的事情,比如在一个循环中产生更多的它们!
在线程内部,你应该放一个像这样的检查
while (!Closing)
这样线程就可以在你需要它的时候结束,而不必求助于像t.Abort();
这样的坏东西,当退出时,将关闭设置为true,并执行一个t.Join()
来关闭检查线程。
编辑:
我忘了说闭合应该是一个布尔属性或VOLATILE布尔值,而不是一个简单的布尔值,因为您不能确保线程能够完成(当然,如果您要关闭应用程序,它会完成,但让它们按您的意愿完成是一个很好的实践)。volatile关键字旨在防止(伪)编译器对假定变量值不能更改的代码应用任何优化
发布于 2011-04-30 06:56:06
从你的帖子中并不清楚你到底想做什么,但听起来你应该把你的模型/服务调用放在一个单独的线程上(通过后台工作者或异步委托),并在完成时使用模型/服务调用的回调来通知UI。然后,您的UI线程可以做一些繁忙的事情,比如显示进度条,但不会变得无响应。
发布于 2011-04-30 07:31:39
如果从图形用户界面轮询,请使用(WinForms)计时器。
如果这是某种后台进程,那么您的睡眠()可能是较小的坏处。
https://stackoverflow.com/questions/5840024
复制相似问题