开发者

Async polling useable for GUI thread

开发者 https://www.devze.com 2022-12-30 05:19 出处:网络
I have read that I can use asynchronous call with polling especially when the caller thread serves the GUI. I cannot see how because:开发者_运维问答

I have read that I can use asynchronous call with polling especially when the caller thread serves the GUI. I cannot see how because:开发者_运维问答

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

So how it come it should be good for this purpose? I needed to update my GUI status bar everytime deamon thread did some progress..


You are correct in your while loop stopping the GUI thread, when doing it like that, you don't want to do that.

If you need to poll, it would be better is to set up a Timer, and check whether the work has completed when the timer fires. The Timer can have a small resolution without problems (100 ms for instance), as long as you dont do much work during each tick.

However, I think you would be even better off by using a callback, so you do not need to poll and get notified as soon as your workload is done.


The point of async polling is that you can do other things in between checking IsCompleted — such as servicing GUI events. You could set a timer, for example, to trigger an event several times per second to check whether your asynchronous operation is finished, and use the normal GUI event loop to service those events together with all the other events your GUI receives. That way, your GUI remains responsive, and shortly after the async operation finishes, your timer event handler will notice it.


I was having the same trouble with an old API exposing BeginExecute() and EndExecute(). BeginExecute() started asynchrounous operation and then went silent until it finished executing to the end. But I was needed to update intermediate state of the execution progress in real-time. So I came up with the following solution:

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);

At first I have used

await Task.Yield();

But then I found out that in WPF it won't return the control to GUI, because this loop will have higher priority. That is why I switched to this instruction:

await Dispatcher.Yield(DispatcherPriority.ApplicationIdle);

So now GUI will check and update progress only when it has nothing else to do :)

0

精彩评论

暂无评论...
验证码 换一张
取 消