Reputation: 50728
I'm using Xamarin Forms with Xamarin Studio on a Mac Mini, and I'm having an async/await issue I was hoping someone could help with. I have a button click event defined as:
void LoginButton_Clicked (object sender, EventArgs e)
{
//Do some stuff
this.HandleSignInCompleted(..);
}
This then calls a method to do some user profile initialization, which it needs to contact the server:
async void HandleSignInCompleted(..)
{
var profile = await _profileService.GetAsync ().ConfigureAwait(false);
This waits indefinitely, whether ConfigureAwait
is present or not. The user profile service simple does the following right now (just returns myself for testing):
public async Task<UserProfile> GetAsync()
{
//wrapper around app properties
var accessToken = (string)_appProperties.Get ("token");
//Tried with ConfigureAwait and without
await Task.Delay (100);
//TODO:replace with facebook load
return new UserProfile (..);
}
With ConfigureAwait(false)
, Task.Delay
chokes. Without it, it works, but the debugger crashed. What's going on and how can I resolve this issue so that the AJAX request (when I replace it in the user profile service in the future) will work?
Upvotes: 1
Views: 641
Reputation: 456322
Sync-over-async is an antipattern; you're at the mercy not only of your own code (must use ConfigureAwait(false)
everywhere), but also at the mercy of any libraries you call. In particular, I've run into a similar issue on Xamarin in the past regarding Task.Delay
. And before you try switching it out for a real network call, HttpClient
has the same problem on some mobile platforms (either iOS or Android, don't remember ATM). Not sure if Facebook would have a similar bug or not.
So, in summary, you really just can't do that. Instead, embrace async
all the way:
async Task HandleSignInCompletedAsync(..)
{
var profile = await _profileService.GetAsync ().ConfigureAwait(false);
}
async void LoginButton_Clicked (object sender, EventArgs e)
{
//Do some stuff
await this.HandleSignInCompletedAsync(..);
}
Disable controls if you have to, but don't block. A nice side effect of this approach is that your app is always more responsive.
Upvotes: 2