Recently ran into an issue that I know I’m not the first to run into and definitely won’t be the last that involved an awaitable async process in a .NET project that I thought was worthy of at least a blog post so someone else doesn’t spend the amount of time I did trying to debug it.
In one of our projects we wanted to add some custom cancellation token logic in our API calls to an external service. To do this we had to create a custom HttpClient object and use that to make our calls.
Note: If you are looking for a reliable method for handling timeouts, cancellations, and retries I would highly recommend reading this blog: Transient timeouts and the retry rabbit hole (.Net 4.5)
So we had a call like the sample List call below:
- _client was our custom HttpClient
- CreateClient(_credentials) returned a normal HttpClient with our retry/timeout/cancellation token logic
- The PostAsync ConfigureAwait value is set to false to make it synchronous and make the value of response to be an HttpResponseMessage
I tested this call locally via a console app, it worked flawlessly so I made the change in our Azure web app, built it, again ran tested the call via console app (instead of Postman, mistake #1) and checked it in. Only then did I realize that none of the calls in our API were returning from this service anymore… how could that be??? The call wasn’t throwing an immediate error, it would just not do anything until it finally threw its timeout error.
I made sure the remote service was up, I went back and tested the console app again, still working just fine. Made sure I had made the correct code changes and that the Azure deployment had went through, all correct. What was going on?
I knew I had an interesting issue because the issue was only affecting our Azure web app and not a console app. It was also acting like an async issue, now I just had to find where it was. At first I thought it had to be the cancellation token source code I had added but a quick test of that code by itself told me that was fine. Next I tried creating a dummy HttpClient object and passing in all of the values needed and making the same exact call and it worked. Hmm… ok so its something with the custom object I’m creating.
And then I tried this:
It is essentially the same code, except I moved the HttpClient object creation out of the await call.
This slight change seems to have fixed the issue as all of the calls started working after this fix.
It seems that placing the object creating call in the await line was causing the actual creation of the object to be ‘await’-ed as well which was stopping the rest of the call from completing. Moving this into its own separate line allows for the custom HttpClient to be created and then used during the await PostAsync command without an issue.
Moral of the story:
Don’t await non-awaitable events.