ASP.NET MVC Web应用程序中基于队列的后台处理

如何在ASP.NET MVC Web应用程序中实现后台处理队列? 虽然大多数数据更改,更新等需要立即可见,但还有其他更新不需要实时处理,我希望将其移交给优先级较低的后台进程,后者将按照自己的进度处理它。

例如,采用StackOverflow的徽章奖励系统。 通常你可以采取一种特定的行动来奖励你一个徽章,但实际的“奖励”发生在以后(通常在10分钟到几个小时之后)。 我认为这是通过单独的后台流程完成的,因为SO的工作在获得时立即授予徽章并不重要。

所以,我正在尝试创建某种队列系统,在这种系统中我可以填充任务(比如实现ITask接口的任何东西,它将有一个Process()方法),最终将由一个单独的进程执行。

我将如何实施这样的系统? 想法/提示/示例代码?

谢谢!

Windows服务和MSMQ与它们通信(如果您需要)。

– 编辑

要略微扩大。

您将创建多个服务,具体取决于您要执行的操作,并让它们都运行各种睡眠级别的无尽线程,以执行您想要的操作。 然后,他们将适当地更新数据库,您不必在客户端执行任何操作。

您可能希望从管理角度与它们进行交互,因此您可能有一个MSMQ,他们会监听管理命令。 根据您的实现,您可能由于某种原因需要重新启动它们,或者可能只是“强制”运行他们想要做的任何事情。

因此,您将使用MSMQ专用队列来执行此操作(System.Messaging命名空间)。 关于MSMQ的主要注意事项之一是消息需要<4meg。 因此,如果您打算发送大对象图,请首先序列化到文件,然后只发送文件名。

MSMQ非常漂亮。 如果需要,您可以根据“关联ID”发送,但出于某些有趣的原因,相关ID必须采用以下forms:

{guid}\1 

其他任何东西都不起作用(至少在框架的2.0版本中,代码可能已经改变)。

– 编辑

示例,根据要求:

 using System.Messaging; ... MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue"); queue.Formatter = new BinaryMessageFormatter(); Message m = new Message(); m.Body = "your serialisable object or just plain string"; queue.Send(m); // on the other side MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue"); queue.Formatter = new BinaryMessageFormatter(); Message m = queue.Receive(); string s = m.Body as string; // s contains that string now 

Jeff在http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/上有一篇很棒的文章,展示了他最初是如何实现Stack Overflow的。

虽然它可能不如服务那么可靠,如果这对你来说是一个选项,它在过去对我非常重要的任务很有用,我已经让它在虚拟主机环境中工作。

在ASP.NET MVC中搜索后台进程时发现了这个问题。 (在.NET 4.5.2之后可用)

 public ActionResult InitiateLongRunningProcess(Emails emails) { if (ModelState.IsValid) { HostingEnvironment.QueueBackgroundWorkItem(ct => LongRunningProcessAsync(emails.Email)); return RedirectToAction("Index", "Home"); } return View(user); } 

注意:我个人不会使用Web服务器来运行后台任务。 也不要重新发明轮子,我强烈建议使用Hangfire 。

阅读Hanselman HowToRunBackgroundTasksInASPNET上的这篇精彩文章