[c#] How to correctly write async method?

So I am trying to learn the basics of using 'async' and 'await' in C#, but I am not sure what I am doing wrong here. I am expecting the following output:

Calling DoDownload DoDownload done [...output here...] 

But I don't get the output of the download, and I also expect "done" but that takes a while. Shouldn't that be output immediately? Also, I can't seem to get the string result either. Here is my code:

namespace AsyncTest {     class Program     {         static void Main(string[] args)         {             Debug.WriteLine("Calling DoDownload");             DoDownloadAsync();             Debug.WriteLine("DoDownload done");         }          private static async void DoDownloadAsync()         {             WebClient w = new WebClient();              string txt = await w.DownloadStringTaskAsync("http://www.google.com/");             Debug.WriteLine(txt);         }     } } 

This question is related to c# async-await c#-5.0

The answer is


To get the behavior you want you need to wait for the process to finish before you exit Main(). To be able to tell when your process is done you need to return a Task instead of a void from your function, you should never return void from a async function unless you are working with events.

A re-written version of your program that works correctly would be

class Program {     static void Main(string[] args)     {         Debug.WriteLine("Calling DoDownload");         var downloadTask = DoDownloadAsync();         Debug.WriteLine("DoDownload done");         downloadTask.Wait(); //Waits for the background task to complete before finishing.      }      private static async Task DoDownloadAsync()     {         WebClient w = new WebClient();          string txt = await w.DownloadStringTaskAsync("http://www.google.com/");         Debug.WriteLine(txt);     } } 

Because you can not await in Main() I had to do the Wait() function instead. If this was a application that had a SynchronizationContext I would do await downloadTask; instead and make the function this was being called from async.


You are calling DoDownloadAsync() but you don't wait it. So your program going to the next line. But there is another problem, Async methods should return Task or Task<T>, if you return nothing and you want your method will be run asyncronously you should define your method like this:

private static async Task DoDownloadAsync()     {         WebClient w = new WebClient();          string txt = await w.DownloadStringTaskAsync("http://www.google.com/");         Debug.WriteLine(txt);     } 

And in Main method you can't await for DoDownloadAsync, because you can't use await keyword in non-async function, and you can't make Main async. So consider this:

var result = DoDownloadAsync();  Debug.WriteLine("DoDownload done"); result.Wait();