繁体   English   中英

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?

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

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

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

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

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

在控制器上使用Async / Await是否有帮助?

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

我当前的设置如下

控制者

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与线程?

这种方法仍然安全吗?

从来都不安全。

在控制器上使用Async / Await是否有帮助?

没有。

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

我有一个AspNetBackgroundTasks库 ,该基本上与QueueBackgroundWorkItem做相同的事情(有细微的差别)。 然而...

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

是。 这是唯一可靠的方法。 这就是我在博客文章中所说的“适当的分布式体系结构”。

不,这不安全。 在服务器上创建一个服务应用程序来处理这些请求并发布结果。 如果您托管在Azure上,请利用其WebJob服务。

暂无
暂无

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

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