I am making some probes with async CTP but I don’t get a good result, because the GUI is blocked.
I have an WPF application with a button and a textBox for a log. Then I have this code:
private async void btnAsync01_Click(object sender, RoutedEventArgs e)
{
UpdateTxtLog("Enter in Button Async01: " + System.DateTime.Now);
await metodo01Async();
UpdateTxtLog("Exit button Async01: " + System.DateTime.Now);
}
private async Task slowMethodAsync()
{
UpdateTxtLog("Enter in slowMethod: " + System.DateTime.Now);
Thread.Sleep(5000);
UpdateTxtLog("Exit slowMethod: " + System.DateTime.Now);
}
If am not wrong, set a method with “sync” (click event in this case), it let the method use the await, to return the point to execution to the method which call the actual method, then the execution return to the GUI.
So in the GUI,I click the button, then in the click event await to the slowMethod, how I use await with the slowMethod the control should be returned to the GUI, and then the GUI should not be blocked. However, the GUI is blocked and the txtLog not show any information until slowMethod finish.
Is this because slowMethod is executed in the same thread than the GUI? If I am wrong, with async normally use the same thread than the method which call the await method, but I think that the reason of the async avoid this.
How can I simulate an slowMethod without thread.Sleep? Perhaps this is the problem, because in slowMethod I sleep the thread, and the thread of slowMethod is the same than the GUI.
This makes me think that is always recommended execute in other thread the code of the async methods? If this is correct, which is the sense to use async if also I need to use task for not blocking the main thread?
When to use async and when to use tasks?
For this probes, I am following the examples in this web: http://www.codeproject.com/Articles/127291/C-5-0-vNext-New-Asynchronous-Pattern
In this example, it’s used client.DownloadStringTaskAsync as slowMethod, but in my case, instead of using a WebClient, I use a dummy method, with a sleep to simulate a slowMethod. I think that is the unique difference.
Thanks.
Daimroc.
Simulate waits using
await TaskEx.Delay(5000), which executes an asynchronous sleep/delay.You may also want to read up some more on
async/await. There are several good Channel9 videos; Stephen Toub, Eric Lippert, and many other Microsoft bloggers have excellent overviews. Jon Skeet’s “eduasync” blog series is also good for really going deep. I’ve written up an async intro on my own blog, as have many others.Here’s how
asyncandawaitreally work, in a nutshell:asynckeyword only enables theawaitkeyword. That is all. It does not run the method on a background thread.awaitonly acts asynchronously if its “awaiter” is not completed.So in your case,
btnAsync01_ClickandslowMethodAsyncboth run on the UI thread.slowMethodAsyncwill run synchronously (executingThread.Sleep), and then return tobtnAsync01_Click, which awaits the already-completed task. Since the task is already completed,btnAsync01_Clickjust continues executing without yielding to the UI message loop.If you replace
Thread.Sleepwithawait TaskEx.Delay, thenbtnAsync01_Clickwill start running on the UI thread, and will callslowMethodAsync(also running on the UI thread). WhenslowMethodAsyncawaits the delay (which is not completed), it will return an incomplete task tobtnAsync01_Click.btnAsync01_Clickwillawaitthat task (which is not completed), and will return to the UI loop.When the delay expires, it will complete, and
slowMethodAsyncwill resume (on the UI thread). WhenslowMethodAsynccompletes, its returned task will complete, andbtnAsync01_Clickwill resume (on the UI thread).