UWP 10 C# HttpResponseMessage 任务冻结

UWP 10 C# HttpResponseMessage task freezes

我无法通过搜索找到任何有类似问题的人所以:

我正在尝试使用 HttpClient 从服务器获取 XML,但我的 UI 在第 "task.Wait()" 行奇怪地冻结了。这是代码:

public void register() {
    String data = "register=" + (accountName) + "&email0=" +
                (email) + "&email1=" + (otherEmail);
    var task = MakeRequest(data);
    task.Wait();                  //freezes here
    var response = task.Result;
    String resultstring = response.Content.ReadAsStringAsync().Result;
}

private static async Task<System.Net.Http.HttpResponseMessage> MakeRequest(String data)
{
     var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
     var httpClient = new System.Net.Http.HttpClient();
     System.Net.Http.HttpResponseMessage responseMessage=null;
     try
     {
         responseMessage = await httpClient.PostAsync(server, content);
     }
     catch(Exception ex)
     {
         responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);
     }
        return responseMessage;
 }

非常感谢任何帮助!

它根本没有奇怪地冻结 - 它完全合理地冻结。

您正在调用 task.Wait(),这会阻止您的 UI 线程执行更多工作,直到该任务完成。但是,当 httpClient.PostAsync 返回的任务完成时,该任务本身需要返回到 UI 线程,以便继续执行异步方法的其余部分。

基本上,您不应该使用 Task.Wait()Task.Result,除非您确定 任务本身不会被阻塞等待继续在您当前正在执行的线程上。

理想情况下,您的 register 方法(应该是 Register 以遵循 .NET 命名约定)也应该是异步的,这样您就可以等待 MakeRequest 返回的任务。

此外,您可能应该更改 MakeRequest 等待任务的方式 - 因为该方法的其余部分 真的 不需要 运行 UI 线程,你可以使用:

responseMessage = await httpClient.PostAsync(server, content).ConfigureAwait(false);

最后,这一行:

responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);

... 如果执行,将抛出 NullReferenceException。如果抛出异常,responseMessage 仍将为 null。

Jon Skeet 的回答解决了我的问题,这里是工作代码,如果其他初学者遇到同样的问题。

public async void Register{
        String data = "register=" + (accountName) + "&email0=" +
            (email) + "&email1=" + (otherEmail);
        var task = await MakeRequest(data);
        String resultstring = taskContent.ReadAsStringAsync().Result;
}

private static async Task<System.Net.Http.HttpResponseMessage> MakeRequest(String data)
{
    var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
    var httpClient = new System.Net.Http.HttpClient();
    return await httpClient.PostAsync(server, content).ConfigureAwait(false);
}

非常感谢!