Suresh Kumar R
Suresh Kumar R

Reputation: 67

How to call asynchronous method synchronously in Windows Phone 8

We have existing iOS application developed using Xamarin.Forms. Now we want to extend to both Android and Windows Phone. In the existing application, all the web service calls are made synchronously. Windows phone supports only asynchronous calling, so we thought of wrapping the asynchronous calls to synchronous.

We are using HttpClient.PostAsync method to access the service. Once the execution hits PostAsync method, the phone hangs. The code to call the service is as follows:

private static async void CallService(System.Uri uri)
{
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Host = uri.Host;
        client.Timeout = System.TimeSpan.FromSeconds(30);
        HttpContent content = new StringContent("", Encoding.UTF8, "application/xml");

        var configuredClient = client.PostAsync(uri, content).ConfigureAwait(false);
        var resp = configuredClient.GetAwaiter().GetResult();
        resp.EnsureSuccessStatusCode();
        responseString = resp.StatusCode.ToString();
        resp.Dispose();

        client.CancelPendingRequests();
        client.Dispose();
    }
}

I know this is because of blocking the UI thread, so only I implemented ConfigureAwait(false) but that didn't work at all. I tried with System.Net.WebClient also but the same result.

Now, how I will make this asynchronous call to process synchronously in Windows Phone 8?

Upvotes: 3

Views: 808

Answers (1)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

First of all avoid using async void methods,because you can't easily wait for its completion. Return Task instead, being inside async method you don't need to do something special to return a Task. Compiler does all the work for you.

You need to await the call to HttpClient.PostAsync, that should be enough to keep the UI responsive.

private static async Task CallService(System.Uri uri)
{
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Host = uri.Host;
        client.Timeout = System.TimeSpan.FromSeconds(30);
        HttpContent content = new StringContent("", Encoding.UTF8, "application/xml");

        var resp = await client.PostAsync(uri, content);// Await it
        resp.EnsureSuccessStatusCode();
        responseString = resp.StatusCode.ToString();
        resp.Dispose();

        client.CancelPendingRequests();
    }
}

Note: I've removed the ConfigureAwait(false) as that's not required. If you really need it, you may add it back.

Upvotes: 5

Related Questions