3

I am running into a deadlock situation when trying to post to WebApi 2 from WebApi 1 using HttpClient PostAsync and using async and await.

Below is WebAPI 1:

public HttpResponseMessage Get([FromUri]int oid) 
{
    var orderdetails = _orderServices.GetOrderDetails(oid);

    var xml = new XmlMediaTypeFormatter();
    xml.UseXmlSerializer = true;
    string orderdetailsser = Serialize(xml, orderdetails);

    var result = PostXml(orderdetailsser);

    return Request.CreateResponse(HttpStatusCode.OK);
}

public static async Task<HttpResponseMessage> PostXml(string str)
{
    using (var client = new HttpClient())
    {

        client.BaseAddress = new Uri("http://localhost:58285/");

        var content = new StringContent(str);
        var response = await client.PostAsync("api/default/ReceiveXml", content).ConfigureAwait(false);
        return response;
    }

}

And WebApi2:

[System.Web.Http.HttpPost]
public HttpResponseMessage ReceiveXml(HttpRequestMessage request)
{

    var xmlDoc = new XmlDocument();
    xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);

    xmlDoc.Save(@"C:\xmlfiles\xml2.xml");

    XmlSerializer deserializer = new XmlSerializer(typeof(OrderInfoModel));
    TextReader reader = new StreamReader(@"C:\xmlfiles\xml2.xml");
    object obj = deserializer.Deserialize(reader);
    OrderInfoModel orderdetails = (OrderInfoModel)obj;
    reader.Close();

    var patient_id = _patientServices.ProcessPatient(orderdetails.Patient, orderdetails.OrderInfo);
    var orderid = _orderServices.ProcessOrder(orderdetails.Patient, orderdetails.OrderInfo, patient_id);

    if (orderdetails.OrderNotes != null && orderdetails.OrderNotes.Count() > 0)
    {
        var success = _orderServices.ProcessOrderNotes(orderid, orderdetails.OrderNotes);
    }

    var prvid = _orderServices.ProcessOrderProvider(orderid, orderdetails.ReferringProvider);

    var shpngid = _orderServices.ProcessOrderShipping(orderid, orderdetails.ShippingInfo);

    var payerid = _orderServices.ProcessOrderPayer(orderid, orderdetails.Insurances);

    return Request.CreateResponse(HttpStatusCode.OK, orderid);
}

I am not getting any response back to WebAPI 1 from WebAPI 2. I have gone through several articles online about deadlock situation. However, I am unable to resolve the deadlock in my case. What am I doing wrong here? Am I using async and await properly?

6
  • Looks like Classic deadlock situation, answer at stackoverflow.com/questions/17248680/… Commented Dec 24, 2017 at 21:39
  • Hello Orel Eraki - I have gone through the article you suggested. I am still unable to fix the deadlock. Commented Dec 24, 2017 at 22:17
  • Possible duplicate of await works but calling task.Result hangs/deadlocks Commented Dec 24, 2017 at 22:17
  • Hello Orel Eraki/David, Can any one of you just modify my code ? I have been trying to modify it according to articles but its still not working? Any help from you in modifying my code is greatly appreciated Commented Dec 24, 2017 at 22:20
  • 2
    Thank you Orel and David for your help. Your links were very informative. Commented Dec 25, 2017 at 0:37

1 Answer 1

1

To build off my comment above, modify your code so that you are not blocking on an async operation. Additionally _orderServices.GetOrderDetails(oid); sounds like a method that hits a database and as such should be await _orderServices.GetOrderDetailsAsync(oid); wherein you use the whatever async api is available for your database access.

[HttpGet()]
public async Task<HttpResponseMessage> Get([FromUri]int oid) {
    var orderdetails = _orderServices.GetOrderDetails(oid);

    var xml = new XmlMediaTypeFormatter();
    xml.UseXmlSerializer = true;
    string orderdetailsser = Serialize(xml, orderdetails);

    var result = await PostXml(orderdetailsser);

    return Request.CreateResponse(HttpStatusCode.OK);
}

public static async Task<HttpResponseMessage> PostXml(string str) {
    using(var client = new HttpClient()) {

        client.BaseAddress = new Uri("http://localhost:58285/");

        var content = new StringContent(str);
        var response = await client.PostAsync("api/default/ReceiveXml", content).ConfigureAwait(false);
        return response;
    }

}

[HttpPost()]
public async Task<HttpResponseMessage> ReceiveXml(HttpRequestMessage request) {

    var xmlDoc = new XmlDocument();
    xmlDoc.Load(await request.Content.ReadAsStreamAsync());

    xmlDoc.Save(@"C:\xmlfiles\xml2.xml");

    XmlSerializer deserializer = new XmlSerializer(typeof(OrderInfoModel));
    TextReader reader = new StreamReader(@"C:\xmlfiles\xml2.xml");
    object obj = deserializer.Deserialize(reader);
    OrderInfoModel orderdetails = (OrderInfoModel)obj;
    reader.Close();

    var patient_id = _patientServices.ProcessPatient(orderdetails.Patient, orderdetails.OrderInfo);
    var orderid = _orderServices.ProcessOrder(orderdetails.Patient, orderdetails.OrderInfo, patient_id);

    if(orderdetails.OrderNotes != null && orderdetails.OrderNotes.Count() > 0) {
        var success = _orderServices.ProcessOrderNotes(orderid, orderdetails.OrderNotes);
    }

    var prvid = _orderServices.ProcessOrderProvider(orderid, orderdetails.ReferringProvider);

    var shpngid = _orderServices.ProcessOrderShipping(orderid, orderdetails.ShippingInfo);

    var payerid = _orderServices.ProcessOrderPayer(orderid, orderdetails.Insurances);

    return Request.CreateResponse(HttpStatusCode.OK, orderid);
}

Resources

Don't Block on Async Code

Avoid Async Void

Sign up to request clarification or add additional context in comments.

1 Comment

Hello J Steward - Thanks a lot for all your help. I was finally able to figure it out. It turns out it was the await in API 2 as well as incorrectly placed breakpoints. However you made my day by correctly pointing out where I need to place the async. Merry Xmas!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.