异步轮询可用于GUI线程

时间:2010-05-16 11:23:33

标签: c# asynchronous

我已经读过,我可以使用带轮询的异步调用,尤其是当调用者线程为GUI提供服务时。我看不出因为:

while(AsyncResult_.IsCompleted==false) //this stops the GUI thread
{
}

那怎么来它应该有益于这个目的?每当deamon线程取得一些进展时,我都需要更新我的GUI状态栏。

3 个答案:

答案 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只有在没有其他事情可做的时候才会检查和更新进度:)