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

Ale*_*lex 27 c# asp.net-mvc

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

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

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

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

谢谢!

Noo*_*ilk 20

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

- 编辑

略微扩大.

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

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

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

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

{guid}\1
Run Code Online (Sandbox Code Playgroud)

其他任何东西都不起作用(至少在框架的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
Run Code Online (Sandbox Code Playgroud)


Adr*_*ian 11

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

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


Dha*_*777 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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