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);
}
非常感谢!
我无法通过搜索找到任何有类似问题的人所以:
我正在尝试使用 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);
}
非常感谢!