【发布时间】:2019-08-09 09:08:58
【问题描述】:
我有一个作为 Azure 应用服务托管的 .Net Web Api。 (我必须从 ADF 将其称为网络活动。)
这个 API 有一些代码可以运行很长时间,所以I want to make this Async。
这就是我的测试方式:
[Route("apiA/[controller]")]
[ApiController]
public class AsynccallController : ControllerBase
{
[HttpPost]
public async Task<String> PostA()
{
var strTask = await Longfunction();
return strTask;
}
private Task<string> Longfunction()
{
Thread.Sleep(TimeSpan.FromSeconds(300));
return Task.FromResult("value1");
}
}
根据to this documentation,await 关键字应该在执行睡眠之前将控制权返回给调用者函数(在本例中为邮递员)。但我没有看到这种情况发生。它仍然等待这 300 秒向邮递员发送响应,这就像一个同步调用。为什么?
其次,如果它确实在“等待”时将控制权发回,那么 return 语句何时以及如何将值发回?
谢谢。
【问题讨论】:
-
await确实将控制权(和Task<>对象)返回给调用者,但调用者(.NET Web API 运行时)不会将 HTTP 响应发送回客户端,直到该任务已完成。 -
谢谢@noseratio 有没有办法在任务完成之前发回响应?我需要一种方法来触发并忘记那个 api 调用。我什至不需要得到任何回复。
-
传统上您会使用
HostingEnvironment.QueueBackgroundWorkItem之类的东西,但我认为这在使用 Azure 托管时不起作用。也许,IApplicationLifetime可以提供帮助。不是 Azure 专家,但我认为您应该使用 Azure 队列或 Azure Functions 等专用服务来运行即发即弃任务,您可以从 Web API 启动这些任务,然后在不等待结果的情况下返回。 -
让任务在 HTTP 事务结束后持续存在通常不是一个好主意。当事务结束时,管道被拆除,您的大部分上下文将丢失、处置或处于无效状态。
标签: .net asp.net-web-api async-await azure-web-app-service azure-app-service-plans