【发布时间】: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。你忽略了把手。当开始线程已经超出范围时操作将完成......那又怎样?
标签: c# asp.net-web-api owin azure-service-fabric