我读过我可以使用异步调用与轮询,特别是当调用者线程为GUI提供服务时。我看不到如何,因为:异步轮询可用于GUI线程
while(AsyncResult_.IsCompleted==false) //this stops the GUI thread
{
}
那么它是如何来它应该是好的这个目的?我需要更新我的GUI状态栏每次deamon线程做了一些进步..
我读过我可以使用异步调用与轮询,特别是当调用者线程为GUI提供服务时。我看不到如何,因为:异步轮询可用于GUI线程
while(AsyncResult_.IsCompleted==false) //this stops the GUI thread
{
}
那么它是如何来它应该是好的这个目的?我需要更新我的GUI状态栏每次deamon线程做了一些进步..
你是正确的在你的while循环停止GUI线程,当这样做时,你不想这样做。
如果您需要轮询,最好是设置一个计时器,并检查计时器触发时工作是否完成。定时器可以有一个小的分辨率没有问题(例如100毫秒),只要你在每次打勾时不做太多的工作。
但是,我认为你会比using a callback更好,所以你不需要轮询并在你的工作量完成后立即得到通知。
异步轮询的要点是,您可以在检查IsCompleted
- 例如服务GUI事件之间执行其他操作。例如,您可以设置一个计时器,以每秒触发一次事件来检查异步操作是否完成,并使用正常的GUI事件循环将这些事件与GUI接收的所有其他事件一起处理。这样,您的GUI仍然是响应式的,并且在异步操作完成后不久,您的计时器事件处理程序将会注意到它。
谢谢,我想到了计时器,但由于我没有经历,我认为这是一个坏主意:) – Thomas 2010-05-16 11:30:23
我与旧版API暴露BeginExecute()
和EndExecute()
时遇到同样的问题。 BeginExecute()
开始异步操作,然后沉默,直到它完成执行到最后。但是我需要实时更新执行进度的中间状态。 于是我想出了以下解决方案:
var asyncResult = command.BeginExecute();
while (!asyncResult.IsCompleted)
{
if (command.State != OldState)
{
progress.Report(newState);
}
// Key piece in this polling loop.
await Dispatcher.Yield(DispatcherPriority.ApplicationIdle);
}
command.EndExecute(asyncResult);
起初我用
await Task.Yield();
但后来我发现,在WPF它不会返回控制到GUI,因为这个循环将具有更高的优先权。这就是为什么我切换到该指令:
await Dispatcher.Yield(DispatcherPriority.ApplicationIdle);
所以现在GUI将检查和更新的进展,只有当它没有其他事情做:)
你检查的BackgroundWorker类?看起来像一个很好的解决方案(http://msdn.microsoft.com/en-us/library/hybbz6ke.aspx) – CharlesB 2010-05-16 11:50:46