Why does await not wait?

那年仲夏 提交于 2019-12-10 16:13:13

问题


This is my actual code:

    async Task getData()
    {
        Thread.Sleep(5000);
        Console.WriteLine("Step 1");

        using (HttpClient api = new HttpClient()) 
            await api.GetAsync("http://google.com/").ContinueWith(
                (getTask) =>
                    Console.WriteLine(getTask.Result.StatusCode);
            );

        Console.WriteLine("Step 2");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Task<Task> task = new Task<Task>(getData);
        task.Start();
        task.Wait();
        Console.WriteLine("Step 3");
    }

I get the following output:

Step 1
Step 3
OK
Step 2

Why does Step 3 not come after Step 2?

How do I get it to work in sequence, ie to return to the caller of getData only until everything in getData is done?


回答1:


You should also mark you event handler as async

private async Task button1_Click(object sender, EventArgs e)

and await instead of Wait:

private async Task button1_Click(object sender, EventArgs e)
{
    await getData();

    Console.WriteLine("Step 3");
}

When we use the async/await pattern, we should go this way until the first method initiated it. Otherwise, by calling explicitly Wait or Result, we may run into deadlock issues. Furthermore, calling explicitly those methods you block the executing thread. So you drop the main benefit of using async/await, which is not blocking the executing thread and run on a separate thread some code and once this is done resume the execution of your code from where you stopped.




回答2:


To try and put things simply and clearly - async Task (and <T>) methods are, themselves, responsible for allocating a Task object which represents their completion.

If you find yourself working with async methods and allocating Task objects yourself (either directly, as here, or using static factory methods such as Task.Run), you've got to recognize that more than one Task object now exists. You have to be careful and recognize situations where (as here) you create Tasks that themselves now return Tasks.

It's far better, if possible, to embrace async all the way (as you modify each function to be async, you'll then tend to locate each call site and make that location async as well) and to stop allocating any Tasks yourself.



来源:https://stackoverflow.com/questions/45365214/why-does-await-not-wait

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!