C# OwinCommunicationListener中托管的异步Web Api中的Fire-and-Forget方法
最近,我可以看到我们正在使用的一个代码,它工作得很好,就我个人而言,我不知道为什么 我们有一个web API托管在一个服务结构集群中,该集群托管在OwinCommunicationListener上C# OwinCommunicationListener中托管的异步Web Api中的Fire-and-Forget方法,c#,asp.net-web-api,owin,azure-service-fabric,C#,Asp.net Web Api,Owin,Azure Service Fabric,最近,我可以看到我们正在使用的一个代码,它工作得很好,就我个人而言,我不知道为什么 我们有一个web API托管在一个服务结构集群中,该集群托管在OwinCommunicationListener上 [HttpPost] public async Task<HttpResponseMessage> WebApiMethod(RequestObject request) { string test; SomeObject obj; .... DoSomethin
[HttpPost]
public async Task<HttpResponseMessage> WebApiMethod(RequestObject request)
{
string test;
SomeObject obj;
....
DoSomethingAsync(test, obj);
return this.ActionContext.CreateResponse(HttpStatusCode.OK, new { Status = "Success" });
}
private async Task DoSomethingAsync(string param1, SomeObject param2)
{
.....
await SomeOtherAsyncMethod();
.....
}
然后,API响应几乎是在10秒后立即执行其余代码。因为最初的调用是一个Fire-and-Forget(未等待),所以不应该在那个时候处理主机线程
这里我遗漏了什么。没有任何东西可以将请求对象与DoSomethingAsync联系起来。但是,即使您将RequestObj引用直接传递到DoSomethingAsync中,该方法也会顺利完成,因为当您引用对象时,GC不会收集您的RequestObj。此外,一旦异步执行开始,它就有了自己的生命周期,这意味着回调可能会在另一个线程上完成,但请求处理管道所调度的线程除外。没有任何东西可以将请求对象与DoSomethingAsync联系起来。但是,即使您将RequestObj引用直接传递到DoSomethingAsync中,该方法也会顺利完成,因为当您引用对象时,GC不会收集您的RequestObj。此外,一旦异步执行开始,它就有了自己的生命周期,这意味着回调可能在另一个线程上完成,但请求处理管道所调度的线程除外。我不清楚这一点。为什么您希望从何处出现异常?值得一提的是,ASP.Net中的fire和forget方法几乎总是一个糟糕的想法。你应该使用一个专门用来处理这类事情的库,比如Hangfire。或者,由于您似乎在Azure中,您可以利用它,而不是100%确定调用哪个功能,可能是WebJobs?@fildor我期待着一个例外,因为我没有等待DoSomethingAsync方法,但它还是设法完成了它的工作everytime@DavidG我严格反对使用上面的代码,但我无法解释这一直是如何工作的我不明白为什么你会期望它抛出异常?想象一下用异步句柄实现它。启动返回AsyncHandle的AsyncOp。你忽略了把手。启动线程已超出范围时,操作将完成。。。那又怎样?我不清楚。为什么您希望从何处出现异常?值得一提的是,ASP.Net中的fire和forget方法几乎总是一个糟糕的想法。你应该使用一个专门用来处理这类事情的库,比如Hangfire。或者,由于您似乎在Azure中,您可以利用它,而不是100%确定调用哪个功能,可能是WebJobs?@fildor我期待着一个例外,因为我没有等待DoSomethingAsync方法,但它还是设法完成了它的工作everytime@DavidG我严格反对使用上面的代码,但我无法解释这一直是如何工作的我不明白为什么你会期望它抛出异常?想象一下用异步句柄实现它。启动返回AsyncHandle的AsyncOp。你忽略了把手。启动线程已超出范围时,操作将完成。。。那又怎么样?
await Task.Delay(10000);