OwinCommunicationListener 中托管的 Async Web Api 中的 Fire and Forget 方法
Posted
技术标签:
【中文标题】OwinCommunicationListener 中托管的 Async Web Api 中的 Fire and Forget 方法【英文标题】:Fire and Forget method in Async Web Api hosted in OwinCommunicationListener 【发布时间】:2018-03-01 13:20:58 【问题描述】:最近我可以看到我们正在使用并且运行良好的代码,但我终其一生都无法弄清楚为什么。
我们在通过 OwinCommunicationListener 托管的服务结构集群中托管了一个 Web API。
[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();
.....
据我了解,这应该是 DoSomethingAsync 的方法完成和请求释放之间的竞争条件,如果稍后提前完成,应该抛出 TaskCancelledException 或其他东西,但它永远不会。
我预计会出现一些错误,因为没有等待 DoSomething 任务,但它每次都完成了它的工作。如果我添加
await Task.Delay(10000);
然后 API 响应几乎是即时的,并且在 10 秒后执行其余代码。到那时不应该释放主机线程,因为原始调用是“即发即弃”(未等待)。
我在这里错过了什么。
【问题讨论】:
我不清楚。为什么您期望从哪里出现异常? 值得一提的是,ASP.Net 中的“一劳永逸”方法几乎总是一个糟糕的主意。您应该使用为处理此类事情而构建的库,例如 Hangfire。或者,由于您似乎在 Azure 中,您可以利用它,而不是 100% 确定调用了哪个功能,可能是 WebJobs? @fildor 我期待一个例外,因为我没有等待 DoSomethingAsync 方法,但它仍然以某种方式每次都设法完成其工作 @DavidG 我严格反对使用上面的代码,但我无法解释它是如何一直工作的 我不明白为什么你会期望它抛出异常?想象一下用 AsyncHandles 实现它。您启动返回 AsyncHandle 的 AsyncOp。你忽略了把手。当开始线程已经超出范围时操作将完成......那又怎样? 【参考方案1】:没有任何东西可以将请求对象与 DoSomethingAsync 联系起来。但是,即使您将 RequestObj 引用直接传递给 DoSomethingAsync,该方法也将毫无问题地完成,因为在您引用对象时 GC 不会收集您的 RequestObj。此外,一旦异步执行开始,它就会有自己的生命,这意味着回调可能在另一个线程上完成,但请求处理管道已被分派。
【讨论】:
以上是关于OwinCommunicationListener 中托管的 Async Web Api 中的 Fire and Forget 方法的主要内容,如果未能解决你的问题,请参考以下文章