I'm writing some basic Firebase code in a Xamarin iOS app and am running into a classic deadlock situation with a TaskCompletionSource
.
public Task<string> GetUsers()
{
var tcs = new TaskCompletionSource<string>();
_instance.GetChild("users").ObserveSingleEvent(DataEventType.Value,
x => { tcs.SetResult(x); });
return tcs.Task;
}
When I block on this code like so:
var users = GetUsers().Result;
The application deadlocks.
If I understand correctly, the callback is trying to run on the same context that the .Result
is waiting on.
What I don't understand is that if I modify my code to await the GetUsers()
call in a Task
like so:
var result = Task.Run(
async () => await AppContext.Database.GetUsers().ConfigureAwait(false)
).Result;
It still deadlocks.
What's going on here in the second case? Shouldn't the fact that the code is running on another thread due to the Task.Run
mean that the outside .Result
doesn't block the callback invocation?
EDIT:
Following up on Nkosi's comment I'm asking this because I'm curious as to why the code is blocking. If I await the call
var users = await GetUsers().ConfigureAwait(false);
then the deadlock goes away. I'd just like to understand why it blocks when wrapped in a Task
because based on my (clearly incorrect) understanding of Task.Run
, it shouldn't.