Reputation: 2125
I call aynchronious methods and something deadlocks. Now I don't have any idea why this is happening. I don't think that this is a standard deadlock, because I call Task.Result in Main method - NOT IN UI thread. What's more, I also tried using async Main without any calls to Task. But the result is the same.
Problem is with WinForms project. Everything starts in Main method:
bool res = Task.Run(() => contr.RegisterPremiseAllInOne()).Result;
This is imple call to asynchronious method RegisterPremiseAllInOne in new Task.
What happens next... RegisterPremiseAllInOne works more-like like that (simplified model):
public async Task<bool> RegisterPremiseAllInOne()
{
AppUser loggedAppUser = await appUserContr.GetLoggedAppUser(); // <-- everything works fine here
if(loggedAppUser == null)
return false;
var premises = await GetPremisesForLoggedUser(); //at the end there is a deadlock
}
I will show you now what calls does each and every method do (everything ends up with rest queries to WebApi):
GetLoggedAppUser ->
await API.Users.GetLoggedAppUser() ->
await ClientHelper.GetObjectFromRequest<Appuser>("AppUsers/logged") ->
await SendAsyncRequest() ->
await HttpClient.SendAsync()
I hope this is quite readable.
This path works well. What's interesting, GetPremisesForLoggedUser
is partially convergent with GetLoggedAppUser
and looks like that:
GetPremisesForLoggedUser ->
await API.Premises.GetForLoggedUser() ->
await ClientHelper.GetListFromRequest<premise>("premises/logged") ->
await SendAsyncRequest() ->
await HttpClient.SendAsync()
As you can see there is a straight path. Call to API and eventually sending a http request.
Deadlock is within SendAsync
from HttpClient
. I don't have any idea why. Yet the first path works fine.
On the server side everything fine as well. Server returns successful response. But the client hangs.
I think it should work. I don't mix synchronious with async code. All the methods return Task<T>
and are marked as async.
Maybe someone know where the problem may exists? Maybe you will want to see some screenshots from debug windows: Parallel Stack / Tasks?
Upvotes: 0
Views: 112
Reputation: 2125
OK, thanks to @usr and @Evk I found the bug. It was however standard UI deadlock but little more camouflaged.
Just before I was calling GetPremisesForLoggedUser()
I was CREATING a form using factory (IoC Container):
IPremisePickerView view = objFactory.Resolve<IPremisePickerView>();
var premises = await GetPremisesForLoggedUser();
When a form is created the thread that this form belongs to automatiocally becomes UI thread. This is done in Form class I think.
So it turns out that I was calling await GetPremisesForLoggedUser()
on UI thread. So probably all the task started to run on UI thread (from some point). But does it mean that Task.Run.Result called in Main was blocking UI thread waiting for result? I'm not sure, becase this was called on main thread (in this case NOT UI thread). So if someone could make up my answer it would be nice.
Anyway, after moving form creation below the call to async method everything started working.
Upvotes: 1