我想做几个POST-Request。
我的问题是,应用程序在我Task<...> do_POST()
- 事件await
期间的async void bt_publishPath_Click()
- 函数中随机崩溃。
我可以执行一些POST请求(一切正常),有时await
将阻止,应用程序崩溃System.NullReferenceException
(经过很长时间的等待)。我不明白为什么会这样,因为它第一次起作用。
这是我到目前为止的内容:
我已经注释掉了每个不重要的功能。我已经测试了没有这些代码行的代码,也发生了错误。
// MainWindow
private async void bt_publishPath_Click(object sender, RoutedEventArgs e)
{
// gr_spinner.Visibility = Visibility.Visible;
ApiResponse res = await ApiCall.do_POST(
"/path",
getBasicAuthString(),
flink.getJsonString()
);
// gr_spinner.Visibility = Visibility.Collapsed;
// Globals.errorHandling(res.Statuscode, res.Parameters[0]);
}
// ApiCall static Class
public static Task<ApiResponse> do_POST(string apiPath, string auth, string json)
{
return Task.Run(() =>
{
int statuscode = 0;
HttpWebResponse response = null;
try
{
// HEADER
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiBase + apiPath);
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", auth);
// DATA
byte[] data = Encoding.ASCII.GetBytes(json);
request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
// SEND AND GET RESPONSE
/*
* It seems to be that GetResponse() isn't called correctly.
* The Backend doesn't receive a POST-request and the reponse stays null.
*/
response = (HttpWebResponse)request.GetResponse();
statuscode = (int)response.StatusCode;
}
catch (WebException ex)
{
statuscode = (int)((HttpWebResponse)ex.Response).StatusCode;
}
return new ApiResponse(statuscode, null, new String[] { apiPath });
});
}
其他信息:
在使用async和await执行此操作之前,我尝试使用BackgroundWorker解决此问题。在这种情况下,我遇到了类似的问题:有时前一个POST的backgroundWorker仍然忙,程序无法启动新程序(死锁)。
此外,我发现了一些有趣的东西:async await Task null reference exception
感谢您的帮助!
答案 0 :(得分:2)
在你的catch区块中,你有function removeAnswer(that) {
console.log(that.parent().index());
//that.parent().remove();
}
。
来自MSDN:
如果可以从Internet资源获得响应,则WebResponse实例包含来自Internet资源的错误响应;否则,null。
因此,您的问题是无响应的服务器以及错误处理中的错误
但是不要解决这个问题,查看HttpClient并编写一个新的(HttpWebResponse)ex.Response
。
答案 1 :(得分:1)
<强>解强>
非常感谢Henk Holterman。他给了我建议,使用HttpClient
代替HttpWebRequest
。对于像我这样有同样问题的每个人:你会得到HttpClient作为NuGet-Package。
<强> ApiCall.cs
强>:
private static HttpClient httpClient = new HttpClient();
public static async Task<HttpResponseMessage> do_POST(string apiPath, string auth, string json)
{
HttpResponseMessage response;
StringContent request = new StringContent(json);
request.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth);
try
{
response = await httpClient.PostAsync(new Uri(apiBase + apiPath), request);
}
catch (HttpRequestException ex)
{
Console.WriteLine(ex.Message);
return null;
}
return response;
}
<强> MainWindow.cs
强>:
private async void bt_publishPath_Click(object sender, RoutedEventArgs e)
{
// [...]
HttpResponseMessage res = await ApiCall.do_POST(
"/path",
"admin:123456",
"{ \"hello\" : \"world\" }"
);
// [...]
}