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

Questions with c# tag:

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array How can I add raw data body to an axios request? Couldn't process file resx due to its being in the Internet or Restricted zone or having the mark of the web on the file Convert string to boolean in C# Entity Framework Core: A second operation started on this context before a previous operation completed ASP.NET Core - Swashbuckle not creating swagger.json file Is ConfigurationManager.AppSettings available in .NET Core 2.0? No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization Getting value from appsettings.json in .net core .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Automatically set appsettings.json for dev and release environments in asp.net core? How to use log4net in Asp.net core 2.0 Get ConnectionString from appsettings.json instead of being hardcoded in .NET Core 2.0 App Unable to create migrations after upgrading to ASP.NET Core 2.0 Update .NET web service to use TLS 1.2 Using app.config in .Net Core How to send json data in POST request using C# ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response How to enable CORS in ASP.net Core WebAPI VS 2017 Metadata file '.dll could not be found How to set combobox default value? How to get root directory of project in asp.net core. Directory.GetCurrentDirectory() doesn't seem to work correctly on a mac ALTER TABLE DROP COLUMN failed because one or more objects access this column Error: the entity type requires a primary key How to POST using HTTPclient content type = application/x-www-form-urlencoded CORS: credentials mode is 'include' Visual Studio 2017: Display method references Where is NuGet.Config file located in Visual Studio project? Unity Scripts edited in Visual studio don't provide autocomplete How to create roles in ASP.NET Core and assign them to users? Return file in ASP.Net Core Web API ASP.NET Core return JSON with status code auto create database in Entity Framework Core Class Diagrams in VS 2017 How to read/write files in .Net Core? How to read values from the querystring with ASP.NET Core? how to set ASPNETCORE_ENVIRONMENT to be considered for publishing an asp.net core application? ASP.NET Core Get Json Array using IConfiguration Entity Framework Core add unique constraint code-first No templates in Visual Studio 2017 ps1 cannot be loaded because running scripts is disabled on this system

Questions with async-await tag:

How to correctly write async method? How can I use async/await at the top level? Any difference between await Promise.all() and multiple await? Async/Await Class Constructor Syntax for async arrow function try/catch blocks with async/await Using filesystem in node.js with async / await Use async await with Array.map Using await outside of an async function SyntaxError: Unexpected token function - Async Await Nodejs Using async/await with a forEach loop Combination of async function + await + setTimeout Effectively use async/await with ASP.NET Web API When should I use Async Controllers in ASP.NET MVC? How to wait for a JavaScript Promise to resolve before resuming function? Entity Framework Queryable async Return list from async/await method async await return Task Running multiple async tasks and waiting for them all to complete Call asynchronous method in constructor? Calling async method synchronously Async always WaitingForActivation How to write an async method with out parameter? How can I use Async with ForEach? When correctly use Task.Run and when just async-await async at console app in C#? Is Task.Result the same as .GetAwaiter.GetResult()? Awaiting multiple Tasks with different results Do you have to put Task.Run in a method to make it async? How do you create an asynchronous method in C#? How to safely call an async method in C# without await How to wait for async method to complete? Parallel foreach with asynchronous lambda Cannot implicitly convert type 'string' to 'System.Threading.Tasks.Task<string>' Synchronously waiting for an async operation, and why does Wait() freeze the program here Making interface implementations async How and when to use ‘async’ and ‘await’ How can I wait In Node.js (JavaScript)? l need to pause for a period of time Where do I mark a lambda expression async? Best practice to call ConfigureAwait for all server-side code await vs Task.Wait - Deadlock? If my interface must return Task what is the best way to have a no-operation implementation? Cannot implicitly convert type from Task<> Using async/await for multiple tasks Await operator can only be used within an Async method Nesting await in Parallel.ForEach HttpClient.GetAsync(...) never returns when using await/async How to call asynchronous method from synchronous method in C#? Can constructors be async? Why can't I use the 'await' operator within the body of a lock statement?

Questions with c#-5.0 tag:

How to correctly write async method? async at console app in C#? Do you have to put Task.Run in a method to make it async? How do you create an asynchronous method in C#? How does Task<int> become an int? Using async/await for multiple tasks How would I run an async Task<T> method synchronously?