Asp.Net MVC 5-长期运行的任务-如何确保在IIS回收AppPool时不会抛弃工作线程? [英] Asp.Net MVC 5 - Long Running Task - How to ensure that worker thread won't be thrown away when IIS recycles the AppPool?

查看:175
本文介绍了Asp.Net MVC 5-长期运行的任务-如何确保在IIS回收AppPool时不会抛弃工作线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据处理MVC应用程序,该应用程序可以处理从100MB到2GB的上载文件大小,并且包含一些长时间运行的操作.用户将上传文件,然后将处理这些文件中的数据,然后最后将对数据的一些分析发送给相关的用户/客户端.

I have a data processing MVC application that works with uploaded file sizes ranging from 100MB to 2GB and contains a couple of long running operations. Users will upload the files and the data in those files will be processed and then finally some analysis on the data will be sent to related users/clients.

处理数据至少要花费几个小时,因此为了确保用户不必一直等待,我已经分解了一个单独的任务来执行此长时间运行的操作.这样,一旦文件被服务器接收并存储在磁盘上,用户将获得带有ReferenceID的响应,然后他们可以关闭浏览器.

It will take least a couple of hours to process the data, so in order to make sure the user doesn't have to wait all the way, I've spun up a separate task to do this long running operation. This way, once the files are received by the server and stored on the disk, the user will get a response back with a ReferenceID and they can close the browser.

到目前为止,它一直按预期运行,但是在阅读了有关在MVC中使用即弃模式以及在回收期间IIS抛弃工作线程的问题之后,我对此方法有所关注.

So far, it's been working well as intended but after reading up on issues with using Fire-and-Forget pattern in MVC and worker threads getting thrown away by IIS during recycling, I have concerns about this approach.

这种方法仍然安全吗?如果不是,如何确保正在处理数据的线程在完成处理并将数据发送给客户端之前不会消失? (以相对简单的方式)

Is this approach still safe? If not, How can I ensure that the thread that is processing the data doesn't die until it finishes processing and sends the data to clients? (in a relatively simpler way)

该应用程序在.NET 4.5上运行,所以不要认为我现在可以使用HostingEnvironment.QueueBackgroundWorkItem.

The app runs on .NET 4.5, so don't think I will be able to use HostingEnvironment.QueueBackgroundWorkItem at the moment.

在控制器帮助下使用Async/Await吗?

Does using Async/Await at controller help?

我还考虑过在文件存储到磁盘后,在应用服务器上使用消息队列来存储消息,然后将DataProcessor设置为单独的服务/进程,然后侦听队列.如果队列是可恢复的,那么它将向我保证,即使服务器崩溃或线程在完成数据处理之前被丢弃,消息最终仍将最终得到处理.这是更好的方法吗?

I've also thought of using a message queue on app server to store messages once the files are stored to disk and then making the DataProcessor a separate service/Process and then listen to the queue. If the queue is recoverable, then it will assure me that the messages will always get processed eventually even if the server crashes or the thread gets thrown away before finish processing the data. Is this a better approach?

我当前的设置如下所示

控制器

public ActionResult ProcessFiles() 
{    
    HttpFileCollectionBase uploadedfiles = Request.Files;    

    var isValid = ValidateService.ValidateFiles(uploadedFiles);

    if(!isValid){
        return View("Error");
    }

    var referenceId = DataProcessor.ProcessData(uploadedFiles);

    return View(referenceId);    
}

业务逻辑

public Class DataProcessor 
   {    
     public int ProcessFiles(HttpFileCollectionBase uploadedFiles) 
     {    
      var referenceId = GetUniqueReferenceIdForCurrentSession();

      var location = SaveIncomingFilesToDisk(referenceId, uploadedFiles);

      //ProcessData makes a DB call and takes a few hours to complete. 

      TaskFactory.StartNew(() => ProcessData(ReferenceId,location))
                 .ContinueWith((prevTask) => 
      {
         Log.Info("Completed Processing. Carrying on with other work");

         //Below method takes about 30 mins to an hour
         SendDataToRelatedClients(ReferenceId);  
      }    
      return referenceId;
     }

   }

参考

http://blog.stephencleary .com/2014/06/fire-and-forget-on-asp-net.html

Apppool回收和Asp.net有线程吗?

推荐答案

这种方法仍然安全吗?

Is this approach still safe?

从不安全.

在控制器帮助下使用Async/Await吗?

Does using Async/Await at controller help?

否.

该应用程序在.NET 4.5上运行,所以不要认为我现在可以使用HostingEnvironment.QueueBackgroundWorkItem.

The app runs on .NET 4.5, so don't think I will be able to use HostingEnvironment.QueueBackgroundWorkItem at the moment.

我有一个 AspNetBackgroundTasks库基本上与QueueBackgroundWorkItem一样(略有不同) .但是...

I have an AspNetBackgroundTasks library that essentially does the same thing as QueueBackgroundWorkItem (with minor differences). However...

我还考虑过在文件存储到磁盘后,在应用服务器上使用消息队列来存储消息,然后将DataProcessor设置为单独的服务/进程,然后侦听队列.如果队列是可恢复的,那么它将向我保证,即使服务器崩溃或线程在完成数据处理之前被丢弃后,消息最终仍将最终得到处理.这是更好的方法吗?

I've also thought of using a message queue on app server to store messages once the files are stored to disk and then making the DataProcessor a separate service/Process and then listen to the queue. If the queue is recoverable, then it will assure me that the messages will always get processed eventually even if the server crashes or the thread gets thrown away before finish processing the data. Is this a better approach?

是的.这是唯一可靠的方法.这就是我的博客文章.

Yes. This is the only reliable approach. It's what I call the "proper distributed architecture" in my blog post.

这篇关于Asp.Net MVC 5-长期运行的任务-如何确保在IIS回收AppPool时不会抛弃工作线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆