I'm hitting deadlock even after using ConfigureAwait(false)
, below is the sample code.
As per the sample http://blog.stephencleary.com/2012/02/async-and-await.html (#Avoding Context), this should not have hit dead lock.
This is my class:
public class ProjectsRetriever
{
public string GetProjects()
{
...
var projects = this.GetProjects(uri).Result;
...
...
}
private async Task<IEnumerable<Project>> GetProjects(Uri uri)
{
return await this.projectSystem.GetProjects(uri, Constants.UserName).ConfigureAwait(false);
}
}
This class is from a shared library:
public class ProjectSystem
{
public async Task<IEnumerable<Project>> GetProjects(Uri uri, string userName)
{
var projectClient = this.GetHttpClient<ProjectHttpClient>(uri);
var projects = await projectClient.GetProjects();
// code here is never hit
...
}
Works if I add ConfigureAwait(false) to await call in shared library, where HttpClient call is made:
public class ProjectSystem
{
public async Task<IEnumerable<Project>> GetProjects(Uri uri, string userName)
{
var projectClient = this.GetHttpClient<ProjectHttpClient>(uri);
var projects = await projectClient.GetProjects().ConfigureAwait(false);
// no deadlock, resumes in a new thread.
...
}
I've been going through all blogs found, only difference I find is ConfigureAwait(false) works when used with httpClient.AsyncApi() call!?
Please help clarify!!!
ConfigureAwait(false)
but in your code you say the second example works. Which one is it? – Yuval ItzchakovProjectsRetriever
and works when used inProjectSystem
– Khanh TOI was under assumption, once ConfigureAwait(false) is used (any where in the call stack), execution from that point will not cause deadlock.
It won't capture the context for that await. But break out your invocations and awaits, and you'll find thatProjectSystem.GetProjects
is invoked (and awaits) before you callConfigureAwait(false)
on the task returned byGetProjects
. IMO the best answer is "only provide an asynchronous API", i.e., makeProjectsRetriever.GetProjects()
async. – Stephen ClearyGetProjects()
(the overload with no parameters) is notasync
and does not return aTask
, so you cannot useawait
on it. This code is not even valid. – BlueRaja - Danny Pflughoeft