[英]500 internal server error while using async await in web API
I've a web API on server side as below.我在服务器端有一个 Web API,如下所示。 It is using async-await pattern.
它使用异步等待模式。 All these methods are present inside
MyClassController
class所有这些方法都存在于
MyClassController
类中
[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客户端代码 -> 在网站 #1 上
install
API -> 在网站 #2 上install
applications
API
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.代码不会在任何地方导致错误,但它会向调用客户端返回 500 内部服务器错误代码。 I've two questions here:
我在这里有两个问题:
Register
method should get blocked while calling external website as I'm using await
while waiting for response.Register
方法应该在调用外部网站时被阻止,因为我在等待响应时使用await
。 Note : Same logs get printed in expected order when I debug the install
API with debugger attached in Visual Studio.注意:当我使用 Visual Studio 中附加的调试器调试
install
API 时,会按预期顺序打印相同的日志。
Update : If I make the call to external website client.PostAsync
run synchronously forcefully using Task.Run
then I get 200 OK response.更新:如果我调用外部网站
client.PostAsync
使用Task.Run
强制同步运行,那么我会得到 200 OK 响应。 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.如果我可以触发并忘记对外部网站的调用,并且我的剩余代码可以同步运行以完成 Web API 调用,那么为什么 Web API 会导致错误。
Register
method is async, it returns void, instead of Task, which could be awaited. Register
方法是异步的,它返回void,而不是可以等待的Task。 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:通常,当您在代码中看到 async void 时,这是个坏消息,因为:
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.