简体   繁体   中英

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.

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.

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;
}

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM