0

I'm calling a WEB API with HTTPClient in an App for WP8. When I click a button I look for an user credentials and if it's ok go to the main page. This is my code:

Calling Method

private async void BtnLogin_OnClick(object sender, RoutedEventArgs e)
{
    var user = new User();

    if (user.IsAuthenticated(tbUserName.Text, tbPassword.Text))
    {
        NavigationService.Navigate(new Uri("/MainPage.xaml"));
    }
}

User Class

public class User
{
    private bool? _isAuthenticated;
    public bool IsAuthenticated(string _userName, string _password)
    {
        return (bool)  (_isAuthenticated ?? (_isAuthenticated = AuthenticateAsync(_userName, _password).Result));
    }

    private static async Task<bool> AuthenticateAsync(string userName, string password)
    {
        var baseUrl = string.Format(Constant.AuthenticateAPIUrl, userName, password);
        try
        {
            var client = new HttpClient { BaseAddress = new Uri(baseUrl) };
            var result = await client.PostAsync(baseUrl, new StringContent("")).ConfigureAwait(false);                
            result.EnsureSuccessStatusCode();
        }
        catch (HttpRequestException ex)
        {
            return false;
        }
        return true;
    }
}

The problem is when await is executed, it blocks the App and never returns.

I try a lot of distinct codes but I think I'm lost now!!.

3
  • You can't do that. Never use .Result to synchronously wait for an async task. Commented Mar 10, 2014 at 16:05
  • I tried before without .Result but in that way when I do " if (user.IsAuthenticated(tbUserName.Text, tbPassword.Text))" How can I expect to be true or false??? Commented Mar 10, 2014 at 16:09
  • I got it I think! I have to make the call this way: if (await user.IsAuthenticated(UserName, Password)), correct? Commented Mar 10, 2014 at 16:11

1 Answer 1

3

Calling Task<T>.Result or Task.Wait on the UI thread can cause a deadlock that I explain in full on my blog.

To fix it, replace every use of Result or Wait with await

public async Task<bool> IsAuthenticatedAsync(string _userName, string _password)
{
    return (bool) (_isAuthenticated ?? (_isAuthenticated = await AuthenticateAsync(_userName, _password)));
}

private async void BtnLogin_OnClick(object sender, RoutedEventArgs e)
{
    var user = new User();

    if (await user.IsAuthenticatedAsync(tbUserName.Text, tbPassword.Text))
    {
        NavigationService.Navigate(new Uri("/MainPage.xaml"));
    }
}

Other notes:

  • Don't ignore compiler warnings. Your original code was informing you that your async void BtnLogin_OnClick method didn't have an await.
  • Follow the Task-based Asynchronous Pattern.
Sign up to request clarification or add additional context in comments.

1 Comment

It works for me!! thanks, but I had to delete "await" from the IsAuthenticatedAsync method

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.