Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My async Task always blocks UI

In a WPF 4.5 application, I don't understand why the UI is blocked when I used await + a task :

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        // Task.Delay works great
        //await Task.Delay(5000);

        double value = await JobAsync(25.0);

        MessageBox.Show("finished : " + value.ToString());
    }

    private async Task<double> JobAsync(double value)
    {
        for (int i = 0; i < 30000000; i++)
            value += Math.Log(Math.Sqrt(Math.Pow(value, 0.75)));

        return value;
    }

The await Task.Delay works great, but the await JobAsync blocks the UI. Why ? Thank you.

like image 654
Nico Avatar asked Oct 08 '12 17:10

Nico


People also ask

Does async await block UI thread?

Though it creates a confusion, in reality async and await will not block the JavaScript main thread. Like mentioned above they are just syntactic sugars for promise chaining.

Is async await blocking JavaScript?

await only blocks the code execution within the async function. It only makes sure that the next line is executed when the promise resolves. So, if an asynchronous activity has already started, await will not have an effect on it.

Can async be blocking?

Making blocking calls to async methods transforms code that was intended to be asynchronous into a blocking operation. Doing so can cause deadlocks and unexpected blocking of context threads.

Is async await blocking C#?

The await operator doesn't block the thread that evaluates the async method. When the await operator suspends the enclosing async method, the control returns to the caller of the method.


2 Answers

You should be getting a warning about JobAsync - it contains no await expressions. All your work is still being done on the UI thread. There's really nothing asynchronous about the method.

Marking a method as async doesn't make it run on a different thread - it's more that it makes it easier to join together asynchronous operations, and come back to the appropriate context.

I suspect it would be a good idea to take a step back and absorb some of the materials about async on MSDN... this is a good starting point...

like image 97
Jon Skeet Avatar answered Oct 30 '22 04:10

Jon Skeet


Try this:

private Task<double> JobAsync(double value)
{
    return Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 30000000; i++)
            value += Math.Log(Math.Sqrt(Math.Pow(value, 0.75)));

        return value;
    });
}
like image 31
L.B Avatar answered Oct 30 '22 05:10

L.B