简体   繁体   English

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

[英]Running awaitable task asynchronously in asp.net

I have the following action in my controller:我的控制器中有以下操作:

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

The controller needs to handle a task that takes several minutes.控制器需要处理需要几分钟的任务。
Is this the correct way to release researchService.RunAsync to handle its job?这是发布researchService.RunAsync来处理其工作的正确方法吗?

Or is there a better approach.或者有更好的方法。

Thanks谢谢

If you are wanting to check that a process is already running, you could mark it as in progress somewhere on the server side (in a task in the database or such) and then when displaying the UI call a method on the server to check the state of your in progress flag.如果您想检查一个进程是否已经在运行,您可以在服务器端的某处(在数据库中的任务中)将其标记为正在进行,然后在显示 UI 时调用服务器上的一个方法来检查您正在进行的标志的状态。

that way the UI could navigate away from that page and return to still see that the process had been started这样 UI 就可以离开那个页面并返回到仍然看到进程已经开始

You can do that if RunAsync is making I/O requests , but you wouldn't return a Task :如果RunAsync正在发出 I/O requests ,您可以这样做,但您不会返回Task

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

That will start running RunAsync on the same thread, just like any other method.这将开始在同一线程上运行RunAsync ,就像任何其他方法一样。 At the first await in RunAsync that acts on an incomplete Task , RunAsync will return its own incomplete Task , at which point control returns back to your Run action and your object is returned.RunAsync中第一次await处理未完成的TaskRunAsync将返回其自己未完成的Task ,此时控制权返回到您的Run操作并返回您的object You won't be waiting for whatever I/O operation RunAsync makes.您不会等待RunAsync进行的任何 I/O 操作。

If RunAsync is taking a long time because of CPU calculations (not I/O), then that won't do anything for you because, remember, it starts running on the same thread.如果RunAsync由于 CPU 计算(而不是 I/O)而花费很长时间,那么这对您没有任何作用,因为请记住,它开始在同一线程上运行。 You will have to start it on another thread, which you can do using Task.Run :您必须在另一个线程上启动它,您可以使用Task.Run

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

But!但!

In both cases, ASP.NET will have no idea that RunAsync is running in the background.在这两种情况下,ASP.NET 都不知道RunAsync在后台运行。 If the IIS app pool is shut down or recycled for any reason, that job will be killed part way through.如果 IIS 应用程序池因任何原因关闭或回收,该作业将在中途终止。 Note that by default, IIS is configured to shut down an app pool after 20 minutes of no HTTP requests coming in.请注意,默认情况下,IIS 配置为在 20 分钟没有 HTTP 请求进入后关闭应用程序池。

If that is unacceptable to you, then you're better off writing the job to a queue in a database or something and doing that background processing in a Windows service.如果这对您来说是不可接受的,那么您最好将作业写入数据库或其他东西中的队列,然后在 Windows 服务中进行后台处理。

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

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