首页 > 解决方案 > .NET MVC:在服务器上执行繁重的任务,然后在完成时向用户发送电子邮件,以便用户可以离开站点而不是等待?

问题描述

场景:一个按钮允许用户合并大量 PDF 文档以下载为单个 PDF。目前,在用户必须等待下载开始时,获取所有 PDF 和合并的操作可能需要一分钟或更长时间。

我的目标是让用户愿意离开。我想到的解决方案是在服务器的后台合并文档,然后在完成后通过电子邮件将链接发送给用户,但我对其他解决方案持开放态度。

我不明白的是如何在后台异步执行合并。使用 .NET、MVC 5、DevExpress。

代码看起来有点像:

$.ajax({
   type: "POST",
   url: '@Url.Action("ExportMergedDocuments_PersonnelId", "Personnel", new { personnelId = Model.Id })',
}).done(function(data) {
   window.location.href = '@Url.RouteUrl(new { Controller = "Personnel", Action = "Download"})/?file=' + data.fileName; }
});
[HttpPost]
public JsonResult ExportMergedDocuments_PersonnelId(int PersonnelId)
{
   var allDocuments = new DataSet();
   allDocuments.Merge(GetDocuments((int)PersonnelId, ".....1").Tables[0]);
   allDocuments.Merge(GetDocuments((int)PersonnelId, ".....2").Tables[0]);

   string fileName = $"merged__{DateTime.Now.ToString("yyyyMMddHHmm")}.pdf";
   if (MergePdfSet(fileName, allDocuments))
      return Json(new { fileName });
   // else error msg
}

下载文件:

[HttpGet]
public ActionResult Download(string file)
{
   return File(..fullpath.., "application/pdf", file);
}

合并PDF:

public bool MergePdfSet(string fileName, DataSet allDocuments)
{
   bool merged = false;
   string fullPath = Path.Combine(Server.MapPath("~/App_Data/temp/"), fileName);
   using (var pdfDocumentProcessor = new PdfDocumentProcessor())
   {
      pdfDocumentProcessor.CreateEmptyDocument(fullPath);
      foreach (DataRow row in allDocuments.Tables[0].Rows)
      {
         var documentId = (int)row["DocumentID"];
         var fetchedDocument = GetFile(documentId);
         pdfDocumentProcessor.AppendDocument(fetchedDocument);
         merged = true;
      }
   }
   return merged;
}

标签: c#asp.net-mvcasynchronousiisserver

解决方案


想到了两个选择:

  1. 创建一个新线程并在那里运行代码,但不要等待它。
  2. 使用 Hangfire ( https://www.hangfire.io/ ),您可以轻松入队工作。

推荐阅读