await without c# Calling async method synchronously

3 Answers

You should get the awaiter (GetAwaiter()) and end the wait for the completion of the asynchronous task (GetResult()).

string code = GenerateCodeAsync().GetAwaiter().GetResult();
c# call async method and wait

I have an async method:

public async Task<string> GenerateCodeAsync()
    string code = await GenerateCodeService.GenerateCodeAsync();
    return code;

I need to call this method from a synchronous method.

How can I do this without having to duplicate the GenerateCodeAsync method in order for this to work synchronously?


Yet no reasonable solution found.

However, i see that HttpClient already implements this pattern

using (HttpClient client = new HttpClient())
    // async
    HttpResponseMessage responseAsync = await client.GetAsync(url);

    // sync
    HttpResponseMessage responseSync = client.GetAsync(url).Result;

I need to call this method from a synchronously method.

It's possible with GenerateCodeAsync().Result or GenerateCodeAsync().Wait(), as the other answer suggests. This would block the current thread until GenerateCodeAsync has completed.

However, your question is tagged with, and you also left the comment:

I was hoping for a simpler solution, thinking that handled this much easier than writing so many lines of code

My point is, you should not be blocking on an asynchronous method in ASP.NET. This will reduce the scalability of your web app, and may create a deadlock (when an await continuation inside GenerateCodeAsync is posted to AspNetSynchronizationContext). Using Task.Run(...).Result to offload something to a pool thread and then block will hurt the scalability even more, as it incurs +1 more thread to process a given HTTP request.

ASP.NET has built-in support for asynchronous methods, either through asynchronous controllers (in ASP.NET MVC and Web API) or directly via AsyncManager and PageAsyncTask in classic ASP.NET. You should use it. For more details, check this answer.

To prevent deadlocks I always try to use Task.Run() when I have to call an async method synchronously that @Heinzi mentions.

However the method has to be modified if the async method uses parameters. For example Task.Run(GenerateCodeAsync("test")).Result gives the error:

Argument 1: cannot convert from 'System.Threading.Tasks.Task<string>' to 'System.Action'

This could be called like this instead:

string code = Task.Run(() => GenerateCodeAsync("test")).Result;