简体   繁体   中英

500 internal server error while using async await in web API

I've a web API on server side as below. It is using async-await pattern. All these methods are present inside MyClassController class

[Route("install")]
public async Task<IHttpActionResult> InstallProduct()
{ 
   Log("milestone1");
   Install();
   Log("milestone6");
}

private bool Install()
{
   MyClass.Register();        
   Log("milestone5");
}

private static async void Register()
{
    Log("milestone2");
    using (HttpClientHandler handler = new HttpClientHandler())
    {
        using (var client = new HttpClient(handler))
        {
            var method = "http://BaseUrlOfWebsite#2/api/applications";
            using (MultipartFormDataContent form = new MultipartFormDataContent())
            {
                //make POST API call into website # 2
                var response = await client.PostAsync(method, form);
                Log("milestone3");
            }
       }
   }
   Log("milestone4");
}

Overall call is like this:

Client code -> install API on website # 1 -> applications API on website # 2

My expected log statements are in below order:

milestone1
milestone2
milestone3
milestone4
milestone5
milestone6

Actual log order that I see in log files is as below:

milestone1
milestone2
milestone5
milestone6
milestone3
milestone4

Code doesn't causes error anywhere but it returns 500 internal server error code to calling client. I've two questions here:

  1. Why the logs are not as per my expectation? My understanding is that Register method should get blocked while calling external website as I'm using await while waiting for response.
  2. Can this out of order code execution cause 500 internal server error even though my code isn't throwing any error?

Note : Same logs get printed in expected order when I debug the install API with debugger attached in Visual Studio.

Update : If I make the call to external website client.PostAsync run synchronously forcefully using Task.Run then I get 200 OK response. Why web API results in error if I can fire and forget the call to external website and my remaining code can run synchronously to finish the web API call.

Register method is async, it returns void, instead of Task, which could be awaited. And instead of awaiting for task your code is running synchronously.

    [Route("install")]
        public async Task<IHttpActionResult> InstallProduct()
        {
            Log("milestone1");
            await Install();
            Log("milestone6");
        }

        private async Task Install()
        {
            await MyClass.Register();

            Log("milestone5");
        }

        private static async Task Register()
        {
            Log("milestone2");
            using (var handler = new HttpClientHandler())
            {
                using (var client = new HttpClient(handler))
                {
                    var method = "http://BaseUrlOfWebsite#2/api/applications";
                    using (MultipartFormDataContent form = new MultipartFormDataContent())
                    {
                        //make POST API call into website # 2
                        var response = await client.PostAsync(method, form);
                        Log("milestone3");
                    }
                }
            }
            Log("milestone4");
        }

In general, when you see async void in your code it's bad news, because:

you can't wait for its completion (as mentioned in this post already) any unhandled exceptions will terminate your process (ouch!)

Suppose you have a timer event that fires every once in a while and you want to do some asynchronous processing inside the handler, so you proceed to write something along the lines of:

var timer = new Timer();
timer.Elapse += OnTimerFired;
timer.Interval = 1000;
timer.Start();

...

private static async void Register()
{
   await Task.Delay(1000);

   // this is going to terminate your process!
   throw new Exception();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM