locked
HttpClient PostAsync caught in a deadlock RRS feed

  • 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 async

    You 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 62

    Default.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 async

    You 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