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

时间:2014-11-07 13:53:00

标签: c# silverlight windows-phone-8.1

我有一个Windows Phone Silverlight应用程序。我知道我所要求的不是一个好的编程实践,但我仍然不明白为什么这个案例在Silverlight中不起作用。

我要做的是从主线程同步调用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();

我也试过这段代码,但它仍然冻结了:

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

由于某种原因,主线程冻结,代码的执行在Wait()方法停止。有趣的是,这行代码在简单的WPF应用程序,Windows Phone 8.1 RT等中运行良好。

3 个答案:

答案 0 :(得分:1)

阻止UI线程通常是一个坏主意,但在这种情况下,它实际上是必须不做的。

在Windows Phone中发出HTTP请求的所有方式都需要UI线程(由于我不知道的原因)。也就是说,执行请求的方法的某些部分在UI线程中执行。因此,阻止它会阻止请求,因此您将无法获得结果,并且线程永远不会被阻止。

我建议你找到一种方法来做你正在做的事情而不阻止UI线程。我只看到一个你确实需要阻止它的情况......在那种情况下我使用套接字发出了请求,但这只是在你找不到任何其他解决方案时。

答案 1 :(得分:0)

httpClient.SendAsync()将在一个单独的线程上调用。你真的不需要做任何事情。

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

答案 2 :(得分:0)

它可能会阻塞,因为您正在使用Wait()和WaitOne()。这些调用阻止了当前线程。你应该使用await代替。你正在使用await和wait()

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

你可能想要这样的东西。它不会启动新线程,但会运行异步,因此不会阻止UI线程。

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

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