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

时间:2009-08-23 02:57:23

标签: c# asp.net-mvc

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

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

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

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

谢谢!

3 个答案:

答案 0 :(得分:20)

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

- 编辑

略微扩大。

你将创建几个服务,具体取决于你想做什么,让它们都运行各种睡眠级别的无尽线程,做你想做的事。然后,他们将适当地更新数据库,您不必在客户端做任何事情。

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

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

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

{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

答案 1 :(得分:11)

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

上实现Stack Overflow的

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

答案 2 :(得分:5)

在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