Lama Madan
Lama Madan

Reputation: 747

Xamarin HttpClient method GetAsync timeout error

I have created an api to get data but it is showing timeout error. I am calling the function inside main function of Xamarin that is called when app is run.

public MainPage()
    {
        InitializeComponent();
        //this.BindingContext = new PatientViewModel();
        Task<PatientModel> abc = GetPatientData();
    }

my function for api GetAsync call:

public async Task<PatientModel> GetPatientData()
    {
        PatientModel patient = null;
        try
        {
            Uri weburl = new Uri("myuri");
            HttpClient client = new HttpClient();
            Console.WriteLine("a");
            HttpResponseMessage response = await client.GetAsync(weburl);
            Console.WriteLine("b");
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine("in");
                patient = await response.Content.ReadAsAsync<PatientModel>();
                Console.WriteLine("in funciton");
                return patient;
            }
            return patient;
        }catch(Exception ex)
        {
            Console.WriteLine(ex);
            return patient;
        }
    }
}

Code is not showing any error. When execution went to GetAsync statement it waits for a while and exception occurs.

System.Net.WebException: The request timed out. ---> Foundation.NSErrorException: Exception of type 'Foundation.NSErrorException' was thrown.

Upvotes: 1

Views: 517

Answers (2)

Nkosi
Nkosi

Reputation: 247551

Consider using an async event handler along with a static HttpClient

static HttpClient client = new HttpClient();

public MainPage() {
    InitializeComponent();
    loadingData += onLoadingData;        
}

protected override void OnAppearing() {
    //loadingData -= onLoadingData; //(optional)
    loadingData(this, EventArgs.Empty);
    base.OnAppearing();
}

private event EventHandler loadingData = delegate { };

private async void onLoadingData(object sender, EventArgs args) {
    var model = await GetPatientData();
    this.BindingContext = new PatientViewModel(model);
}

public async Task<PatientModel> GetPatientData() {
    PatientModel patient = null;
    try {
        Uri weburl = new Uri("myuri");
        Console.WriteLine("a");
        var response = await client.GetAsync(weburl);
        Console.WriteLine("b");
        if (response.IsSuccessStatusCode) {
            Console.WriteLine("in");
            patient = await response.Content.ReadAsAsync<PatientModel>();
            Console.WriteLine("in funciton");
        }           
    }catch(Exception ex) {
        Console.WriteLine(ex);
    }
    return patient;
}

Using this pattern can help avoid blocking calls and socket exhaustion that can at times lead to deadlocks that could cause the timeouts experienced.

Reference Async/Await - Best Practices in Asynchronous Programming

Reference You're using HttpClient wrong

Upvotes: 2

Enrique Arce
Enrique Arce

Reputation: 21

Try this.

public PatientModel abc { get; set; }

public MainPage()
{
    InitializeComponent();

    Bridge();

    // Using abc
}

public async void Bridge()
{
    abc = new PatientModel();
    abc = await GetPatientData();
}

public async Task<PatientModel> GetPatientData()
{
    PatientModel patient = null;
    try
    {
        Uri weburl = new Uri("myuri");
        HttpClient client = new HttpClient();
        Console.WriteLine("a");
        HttpResponseMessage response = await client.GetAsync(weburl);
        Console.WriteLine("b");
        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine("in");
            patient = await response.Content.ReadAsAsync<PatientModel>();
            Console.WriteLine("in funciton");
            return patient;
        }
        return patient;
    }catch(Exception ex)
    {
        Console.WriteLine(ex);
        return patient;
    }
}

Upvotes: 0

Related Questions