I had a situation recently where I had an ASP.NET WebAPI controller that needed to perform two web requests to another REST service inside its action method. I had written my code to have functionality separated cleanly into separate methods, which looked a little like this example:
public class FooController : ApiController
{
public IHttpActionResult Post(string value)
{
var results = PerformWebRequests();
// Do something else here...
}
private IEnumerable<string> PerformWebRequests()
{
var result1 = PerformWebRequest("service1/api/foo");
var result = PerformWebRequest("service2/api/foo");
return new string[] { result1, result2 };
}
private string PerformWebRequest(string api)
{
using (HttpClient client = new HttpClient())
{
// Call other web API and return value here...
}
}
}
Because I was using HttpClient
all web requests had to be async. I've never used async/await before so I started naively adding in the keywords. First I added the async
keyword to the PerformWebRequest(string api)
method but then the caller complained that the PerformWebRequests()
method has to be async
too in order to use await
. So I made that async
but now the caller of that method must be async
too, and so on.
What I want to know is how far down the rabbit hole must everything be marked async
to just work? Surely there would come a point where something has to run synchronously, in which case how is that handled safely? I've already read that calling Task.Result
is a bad idea because it could cause deadlocks.