繁体   English   中英

在asp.net中异步运行等待任务

[英]Running awaitable task asynchronously in asp.net

我的控制器中有以下操作:

[HttpPost("run")]
public Task<object> Run([FromBody] ResearchRequest researchRequest)
{
   researchService.RunAsync(researchRequest);
   return new{ queued = true   };
}

控制器需要处理需要几分钟的任务。
这是发布researchService.RunAsync来处理其工作的正确方法吗?

或者有更好的方法。

谢谢

如果您想检查一个进程是否已经在运行,您可以在服务器端的某处(在数据库中的任务中)将其标记为正在进行,然后在显示 UI 时调用服务器上的一个方法来检查您正在进行的标志的状态。

这样 UI 就可以离开那个页面并返回到仍然看到进程已经开始

如果RunAsync正在发出 I/O requests ,您可以这样做,但您不会返回Task

[HttpPost("run")]
public object Run([FromBody] ResearchRequest researchRequest)
{
   researchService.RunAsync(researchRequest);
   return new{ queued = true   };
}

这将开始在同一线程上运行RunAsync ,就像任何其他方法一样。 RunAsync中第一次await处理未完成的TaskRunAsync将返回其自己未完成的Task ,此时控制权返回到您的Run操作并返回您的object 您不会等待RunAsync进行的任何 I/O 操作。

如果RunAsync由于 CPU 计算(而不是 I/O)而花费很长时间,那么这对您没有任何作用,因为请记住,它开始在同一线程上运行。 您必须在另一个线程上启动它,您可以使用Task.Run

[HttpPost("run")]
public Task<object> Run([FromBody] ResearchRequest researchRequest)
{
   Task.Run(() => researchService.RunAsync(researchRequest));
   return new{ queued = true   };
}

但!

在这两种情况下,ASP.NET 都不知道RunAsync在后台运行。 如果 IIS 应用程序池因任何原因关闭或回收,该作业将在中途终止。 请注意,默认情况下,IIS 配置为在 20 分钟没有 HTTP 请求进入后关闭应用程序池。

如果这对您来说是不可接受的,那么您最好将作业写入数据库或其他东西中的队列,然后在 Windows 服务中进行后台处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM