Answered by:
HttpClient PostAsync caught in a deadlock

Question
-
User-1641476077 posted
Hi,
I am doing a web page to pull some JSON data from a site and to display this data out to end user.
Below is my code:
protected void Page_Load(object sender, EventArgs e) { startApi().Wait(); lblCookie.Text = message; } protected static async Task<int> startApi() { var responseString = await GetLogin(); return 0; } protected static async Task<string> GetLogin() { var responseString = string.Empty; try { string username = ConfigurationManager.AppSettings["username"]; string password = ConfigurationManager.AppSettings["password"]; string loginUrl = ConfigurationManager.AppSettings["loginUrl"]; using (HttpClient client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>(); postData.Add(new KeyValuePair<string, string>("username", username)); postData.Add(new KeyValuePair<string, string>("password", password)); FormUrlEncodedContent content = new FormUrlEncodedContent(postData);
//code is in deadlock after the line below HttpResponseMessage response = await client.PostAsync(loginUrl, content); if (response.IsSuccessStatusCode) { message += "response ok <br />"; } else { message += "response failed <br />"; } } } catch (Exception exe) { message += "exception: " + exe.Message + "<br />"; } return responseString; }Apparently the code is stuck at the line HttpResponseMessage response = await client.PostAsync(loginUrl, content);
Wednesday, December 19, 2018 2:10 AM
Answers
-
User36583972 posted
Hi bczm8703,But if i use .Result, i will not be able to use the await keyword. i am under the assumption that for HTTPClient, i should be using it with await and asyncYou can use the response.Content.ReadAsStringAsync() to serialize the HTTP content
using (var response = client.PostAsync("/api/FormUrlEncoded", content).Result) { Console.WriteLine(response.StatusCode); string s = await response.Content.ReadAsStringAsync(); }
Best Regards,
Yong Lu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, December 20, 2018 3:27 AM
All replies
-
User-1641476077 posted
i tried adding ConfigureAwait(false) to the 2 lines of code with the await. i got the following exception
Exception: An error occurred while sending the request. Stack Trace: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at _Default.d__4.MoveNext() in d:\projects\IOT Monitoring System\Default.aspx.cs:line 62Default.aspx.cs:line 62 points to
HttpResponseMessage response = await client.PostAsync(loginUrl, content).ConfigureAwait(false);
Wednesday, December 19, 2018 3:26 AM -
User36583972 posted
Hi bczm8703,
//code is in deadlock after the line below HttpResponseMessage response = await client.PostAsync(loginUrl, content);
You have use asynchronous call and it will go async all the way unless you you use .Result.
That is what is causing deadlock.
using (var client = new HttpClient()) { var baseUrl = Request.Url.GetLeftPart(UriPartial.Authority); var uri = new Uri(baseUrl); client.BaseAddress = uri; var values = new List<KeyValuePair<string, string>>(); values.Add(new KeyValuePair<string, string>("customerID", "CUS01")); using (var content = new FormUrlEncodedContent(values)) { using (var response = client.PostAsync("/api/FormUrlEncoded", content).Result) { Console.WriteLine(response.StatusCode); } } }
Best Regards,Yong Lu
Thursday, December 20, 2018 3:09 AM -
User-1641476077 posted
Hi bczm8703,
bczm8703
//code is in deadlock after the line below HttpResponseMessage response = await client.PostAsync(loginUrl, content);
You have use asynchronous call and it will go async all the way unless you you use .Result.
That is what is causing deadlock.
using (var client = new HttpClient()) { var baseUrl = Request.Url.GetLeftPart(UriPartial.Authority); var uri = new Uri(baseUrl); client.BaseAddress = uri; var values = new List<KeyValuePair<string, string>>(); values.Add(new KeyValuePair<string, string>("customerID", "CUS01")); using (var content = new FormUrlEncodedContent(values)) { using (var response = client.PostAsync("/api/FormUrlEncoded", content).Result) { Console.WriteLine(response.StatusCode); } } }
Best Regards,Yong Lu
But if i use .Result, i will not be able to use the await keyword. i am under the assumption that for HTTPClient, i should be using it with await and async
Thursday, December 20, 2018 3:20 AM -
User36583972 posted
Hi bczm8703,But if i use .Result, i will not be able to use the await keyword. i am under the assumption that for HTTPClient, i should be using it with await and asyncYou can use the response.Content.ReadAsStringAsync() to serialize the HTTP content
using (var response = client.PostAsync("/api/FormUrlEncoded", content).Result) { Console.WriteLine(response.StatusCode); string s = await response.Content.ReadAsStringAsync(); }
Best Regards,
Yong Lu
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, December 20, 2018 3:27 AM