【问题标题】:Threading to continue process while web page is left留下网页时线程继续处理
【发布时间】:2015-09-10 22:25:51
【问题描述】:

我已经阅读了很多关于使用 C# 进行线程化的文章,但首先我没有在生产中使用它做任何事情。

我有一个应用程序必须处理一堆文件,然后通过电子邮件发送这些文件。这可能需要 60 秒才能完成。我不希望我的网络应用程序的用户必须等待这些事情处理完毕才能转移到网站的其他部分。

单击按钮会调用 SendEmail 函数。我可以对此代码执行什么操作,以便我的用户可以继续浏览网站,而无需中断我需要在 EmailPDFs 函数中执行的处理?

    [Authorize]
    public ActionResult SendEmail(decimal? id, decimal? id2)
    {
       EmailPDFs(..., ..., ...);  
    }

非常感谢!

【问题讨论】:

  • 例如,我不会在 Web 应用程序中执行此操作,将作业转储到队列中并让外部服务获取并处理作业。
  • 但要计划好如何将成功/失败传达给创建命令的用户。
  • Lloyd,您建议哪种类型的外部服务?感谢劳埃德和马里奥的评论。
  • 这样做有什么害处? Task.Factory.StartNew(() => { EmailPDFs(..., ..., ...); });
  • 危害是 IIS 可以在任务完成之前关闭您的 AppDomain。 AppDomain 仅在您有活动访问者时保持活动状态,如果没有人访问它不会考虑在拆除域之前运行后台线程(想想在您的程序上执行“结束任务”)。请参阅 this answer of mine 的另一个问题,了解如何要求 IIS 在结束任务任务之前给您最多 90 秒的额外时间来完成后台工作。

标签: c# multithreading


【解决方案1】:

这确实是消息队列旨在处理的那种事情。触发一条消息,一个可能独立的服务器上的进程将接收并处理它。完成后,它会将消息发送回服务器上的队列,服务器上的进程会在该队列中接收它并通知您它已完成。然后通知用户工作已完成。

现代消息队列系统可以由数据库(如 Mongo、MySql 或 SQL Server)支持,并且非常健壮。它们的优点在于,它们允许您将长时间运行或 CPU 密集型进程转移到其他服务器上,从而使您的网站保持美观和快速。

可以尝试通过使用 TaskFactory 和所有其他东西(对于许多人来说,这是他们采取的路线),为您的 Web 应用程序添加多线程和并行性,但它没有如果您需要分离您的应用程序并在必要时打破那些占用资源的大块,这将变得非常容易。

我敦促您考虑基于队列的解决方案。


更新:

有关如何实施此类解决方案的示例和信息,请参阅以下内容:

另外,请考虑查看this StackOverflow question 以获取有关所需代码量最少的快速速成课程。

最后一点:MSMQ 内置于某些风格的 Windows 中,可以通过控制面板的添加/删除程序功能添加到其中。但是,您如何安装它取决于您的特定风格和 Windows 版本。一个简单的 Google 搜索将帮助您找到适当的说明。

祝你好运!

【讨论】:

  • 除非您在 4.5.2 上使用 QueueBackgroundWorkItem 注册该线程(或者如果您无法升级到 4.5.2,则使用一些 3rd party library 注册该线程,否则您不应该让线程的生存时间超过页面请求),否则它您的程序很有可能在您的任务完成之前关闭其 AppDomain(如果您注册它,默认情况下您最多只能额外获得 90 秒来完成您的工作)。如果您删除了第 3 段或显示了正确的方式,我会 +1
  • @ScottChamberlain 我个人不提倡在网站上使用 TaskFactory、async、await 或任何其他内容。长时间运行的进程属于单独的服务器,有某种消息传递系统用于通知。您只强调了另一个应该这样做的原因。
  • 如果我要分离我的应用程序的长处理部分,我会怎么做?你能给我一个例子或资源来告诉我这是如何工作的吗?
  • @JHunt 我已更新帖子以提供您要求的信息。
猜你喜欢
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多