我在ASP.NET Web API
行动中的异步任务中有点迷失。我有一个动作:
[HttpPost]
public async Task<HttpResponseMessage> Restart()
{
await AspManager.Restart();
return Request.CreateResponse(HttpStatusCode.OK, new { result = "Success", message = "IIS site successfully restarted" });
}
重启可能会长时间运行,我想等待它然后返回响应。这是长期运行的代码:
public static async Task<Task> Restart()
{
var client = new Client("...");
CheckApiKey(client);
var task = Task.Factory.StartNew(async () =>
{
client.Stop();
await Task.Delay(5 * 1000);
throw new BusinessException("test");
client.Start();
});
return await task;
}
所以在主Restart
方法中,我正在检查密钥,然后我应该停止服务,等待5秒并启动服务。在完成此工作之前,控制器的操作不应返回。但问题是动作会在5秒后抛出BusinessException
。
答案 0 :(得分:2)
您的方法是async Task<Task>
,您正在启动任务并返回该任务。这意味着您刚刚开始返回任务。
关键点是:你正在等待任务创建,而不是它的执行。
将您的方法签名更改为“异步空格”,然后从await Task.Factory.StartNew(() => versus Task.Start; await Task;使用Task.Run()
:
public async Task Restart()
{
// ...
await Task.Run(async () =>
{
client.Stop();
await Task.Delay(5 * 1000);
client.Start();
});
}
答案 1 :(得分:0)
Task.Factory.StartNew
is a dangerous API,正如我在博客上解释的那样。你遇到的问题是它不理解Task.Run
lambdas。 (还有其他问题)。
但是,使用await
不是一个合适的解决方案。它在ASP.NET上适得其反。您应该只使用public static async Task<Task> RestartAsync()
{
var client = new Client("...");
if (CheckApiKey(client))
return;
client.Stop();
await Task.Delay(TimeSpan.FromSeconds(5));
client.Start();
}
:
{{1}}