我已经读过,我可以使用带轮询的异步调用,尤其是当调用者线程为GUI提供服务时。我看不出因为:
while(AsyncResult_.IsCompleted==false) //this stops the GUI thread
{
}
那怎么来它应该有益于这个目的?每当deamon线程取得一些进展时,我都需要更新我的GUI状态栏。
答案 0 :(得分:1)
你在停止GUI线程的while循环中是正确的,当你这样做时,你不想这样做。
如果你需要轮询,最好是设置一个Timer,并在计时器触发时检查工作是否已完成。定时器可以有一个小的分辨率没有问题(例如100毫秒),只要你在每个滴答声中都做不了多少工作。
但是,我认为using a callback会更好,所以一旦工作量完成,您就不需要轮询并收到通知。
答案 1 :(得分:0)
异步轮询的重点是,您可以在检查IsCompleted
之间执行其他操作 - 例如为GUI事件提供服务。例如,您可以设置一个计时器,以便每秒多次触发事件以检查您的异步操作是否已完成,并使用普通的GUI事件循环来为这些事件以及GUI接收的所有其他事件提供服务。这样,您的GUI保持响应,并且在异步操作完成后不久,您的计时器事件处理程序将注意到它。
答案 2 :(得分:0)
我在使用旧的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只有在没有其他事情可做的时候才会检查和更新进度:)