Kristina
Kristina

Reputation: 31

Main thread freezes when waiting for Web service synchronously in Windows Phone Silverlight Application 8/8.1

I have a Windows Phone Silverlight Application. I know that what I am asking is not a good programming practice but still I don't understand why this case is not working in Silverlight.

What I am trying to do is to call Web service from the main thread synchronously waiting for a different thread to do the work.

        HttpClient httpClient = new System.Net.Http.HttpClient();
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "Web service address");

        AutoResetEvent showSplash = new AutoResetEvent(false);
        Thread uiThread = new Thread(async () =>
        {
            await httpClient.SendAsync(request);
            showSplash.Set();
        });

        uiThread.IsBackground = true;
        uiThread.Start();

        showSplash.WaitOne();

Also I've tried this code, but it still freezes:

        HttpClient httpClient = new System.Net.Http.HttpClient();
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "Web service address");

        Task<HttpResponseMessage> response = Task.Run(async () => await httpClient.SendAsync(request));

        response.Wait();

For some reason the main thread freezes and the execution of code stops at the Wait() method. The interesting part is that this line of code works fine in simple WPF application, Windows Phone 8.1 RT etc.

Upvotes: 1

Views: 886

Answers (3)

Simon
Simon

Reputation: 316

It's probably blocking because you are using Wait() and WaitOne(). These calls are blocking the current thread. You should use await instead. You are though using both await and wait()

http://msdn.microsoft.com/en-us/library/hh191443.aspx

You probably want something like this. It will not start a new thread but it will run async so the UI thread is not blocked.

  HttpClient httpClient = new System.Net.Http.HttpClient();
  HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "Web service address");

  Task<HttpResponseMessage> response = await httpClient.SendAsync(request));

Upvotes: 0

Chui Tey
Chui Tey

Reputation: 5564

The httpClient.SendAsync() will be called on a separate thread already. There's nothing you really need to do.

public async void Button1Click(object sender, EventArgs e)
{
    HttpClient httpClient = new System.Net.Http.HttpClient();
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "Web service address");

    button1.Enabled = false;

    await httpClient.SendAsync(request);

    // this line will be called back on the main thread.
    button1.Enabled = true;
}

Upvotes: 0

yasen
yasen

Reputation: 3580

It's generally a bad idea to block the UI thread, but in this case it's actually a must-not-do.

All ways of making an HTTP request in Windows Phone need the UI thread at some point (for reasons unknown to me). That is, some part of the method that does the request is executed in the UI thread. So, blocking it would prevent the request to be made, and so you won't get result and the thread is never unblocked.

I'd suggest that you find a way to do what you're doing without blocking the UI thread. I've seen only one case in which you truly need to block it... and in that case I made the requests using sockets, but that's only in case you can't find ANY other solution.

Upvotes: 1

Related Questions