简体   繁体   English

在Windows Phone Silverlight应用程序8 / 8.1中同步等待Web服务时,主线程冻结

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

I have a Windows Phone Silverlight Application. 我有Windows Phone Silverlight应用程序。 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. 我知道我要问的不是一种好的编程习惯,但是我仍然不明白为什么这种情况在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. 我正在尝试做的是从主线程同步调用Web服务,以等待其他线程完成工作。

        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. 由于某些原因,主线程冻结,并且代码的执行在Wait()方法处停止。 The interesting part is that this line of code works fine in simple WPF application, Windows Phone 8.1 RT etc. 有趣的是,这行代码在简单的WPF应用程序,Windows Phone 8.1 RT等中可以正常工作。

It's generally a bad idea to block the UI thread, but in this case it's actually a must-not-do. 阻塞UI线程通常不是一个好主意,但是在这种情况下,这实际上是必须做的。

All ways of making an HTTP request in Windows Phone need the UI thread at some point (for reasons unknown to me). 在Windows Phone中发出HTTP请求的所有方式在某个时候都需要UI线程(出于我未知的原因)。 That is, some part of the method that does the request is executed in the UI thread. 也就是说,执行请求的方法的某些部分在UI线程中执行。 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. 我建议您找到一种在不阻塞UI线程的情况下执行操作的方法。 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. httpClient.SendAsync()将已经在单独的线程上被调用。 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(). 这可能是因为您正在使用Wait()和WaitOne()。 These calls are blocking the current thread. 这些调用阻止了当前线程。 You should use await instead. 您应该改用await。 You are though using both await and wait() 您虽然同时使用了await和wait()

http://msdn.microsoft.com/en-us/library/hh191443.aspx 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. 它不会启动新线程,但会异步运行,因此不会阻塞UI线程。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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