How Do I Call an Async Method from a Non-Async Method?

Am I missing something?

Yes. Asynchronous code - by its nature - implies that the current thread is not used while the operation is in progress. Synchronous code - by its nature - implies that the current thread is blocked while the operation is in progress. This is why calling asynchronous code from synchronous code literally doesn't even make sense. In fact, as I describe on my blog, a naive approach (using Result/Wait) can easily result in deadlocks.

The first thing to consider is: should my API be synchronous or asynchronous? If it deals with I/O (as in this example), it should be asynchronous. So, this would be a more appropriate design:

public async Task<string> RetrieveHolidayDatesFromSourceAsync() {
    var result = await this.DoRetrieveHolidayDatesFromSourceAsync();
    /** Do stuff **/
    var returnedResult  = this.TransformResults(result); /** Where result gets used **/
    return returnedResult;
}

As I describe in my async best practices article, you should go "async all the way". If you don't, you won't get any benefit out of async anyway, so why bother?

But let's say that you're interested in eventually going async, but right now you can't change everything, you just want to change part of your app. That's a pretty common situation.

In that case, the proper approach is to expose both synchronous and asynchronous APIs. Eventually, after all the other code is upgraded, the synchronous APIs can be removed. I explore a variety of options for this kind of scenario in my article on brownfield async development; my personal favorite is the "bool parameter hack", which would look like this:

public string RetrieveHolidayDatesFromSource() {
  return this.DoRetrieveHolidayDatesFromSourceAsync(sync: true).GetAwaiter().GetResult();
}

public Task<string> RetrieveHolidayDatesFromSourceAsync() {
  return this.DoRetrieveHolidayDatesFromSourceAsync(sync: false);
}

private async Task<string> DoRetrieveHolidayDatesFromSourceAsync(bool sync) {
  var result = await this.GetHolidayDatesAsync(sync);
  /** Do stuff **/
  var returnedResult  = this.TransformResults(result);
  return returnedResult;
}

private async Task<string> GetHolidayDatesAsync(bool sync) {
  using (var client = new WebClient()) {
    return sync
        ? client.DownloadString(SourceURI)
        : await client.DownloadStringTaskAsync(SourceURI);
  }
}

This approach avoids code duplication and also avoids any deadlock or reentrancy problems common with other "sync-over-async" antipattern solutions.

Note that I would still treat the resulting code as an "intermediate step" on the path to a properly-asynchronous API. In particular, the inner code had to fall back on WebClient (which supports both sync and async) instead of the preferred HttpClient (which only supports async). Once all the calling code is changed to use RetrieveHolidayDatesFromSourceAsync and not RetrieveHolidayDatesFromSource, then I'd revisit this and remove all the tech debt, changing it to use HttpClient and be async-only.


public string RetrieveHolidayDatesFromSource() {
    var result = this.RetrieveHolidayDatesFromSourceAsync().Result;
    /** Do stuff **/
    var returnedResult  = this.TransformResults(result.Result); /** Where result gets used **/
    return returnedResult;
}

If you add .Result to the async call, it will execute and wait for the result to arrive, forcing it to be synchronous

UPDATE:

private static string stringTest()
{
    return getStringAsync().Result;
}

private static async Task<string> getStringAsync()
{
    return await Task.FromResult<string>("Hello");
}
static void Main(string[] args)
{
    Console.WriteLine(stringTest());

}

To address the comment: This works without any problems.