C# ASP.NET MVC Web 应用程序中基于队列的后台处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1317641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Queue-Based Background Processing in ASP.NET MVC Web Application
提问by Alex
How can I implement background processing queues in my ASP.NET MVC web app? While most data changes, updates etc. need to be visible immediately, there are other updates that don't need real time processing which I would like to hand off to a lower-priority background process which will take care of it at its own pace.
如何在我的 ASP.NET MVC Web 应用程序中实现后台处理队列?虽然大多数数据更改、更新等需要立即可见,但还有其他不需要实时处理的更新,我想将它们交给低优先级的后台进程,该进程将按照自己的节奏进行处理.
As an example, take StackOverflow's badge award system. Usually you may take a specific action that would award you a badge, but the actual 'award' happens later (typically between 10 minutes and a couple hours later). I assume this is done via a separate background process as it is not critical for SO's workings to award badges immediately when earned.
以 StackOverflow 的徽章奖励系统为例。通常,您可能会采取特定的行动来授予您徽章,但实际的“奖励”发生在更晚的时间(通常在 10 分钟到几个小时之后)。我认为这是通过单独的后台流程完成的,因为 SO 的工作在获得徽章后立即授予徽章并不重要。
So, I'm trying to create some kind of queue system in which I could stuff tasks (say anything implementing ITask interface which will have a Process() method) which will eventually get executed by a separate process.
所以,我正在尝试创建某种队列系统,我可以在其中填充任务(比如实现 ITask 接口的任何东西,它将具有 Process() 方法),最终将由单独的进程执行。
How would I go about implementing such a system? Ideas/Hint/Sample Code?
我将如何实施这样的系统?想法/提示/示例代码?
Thank you!
谢谢!
采纳答案by Noon Silk
Windows Services and MSMQ to communicate with them (if you even need to).
Windows 服务和 MSMQ 与它们通信(如果你甚至需要的话)。
-- Edit
- 编辑
To slightly expand.
稍微展开。
You'll create several services, depending on what you want to do, and have them all run an endless thread of various sleeping levels, to do what you want. They will then update the database appropriately, and you will not have had to do anything on the client side.
您将创建多个服务,具体取决于您想要做什么,并让它们都运行不同睡眠级别的无尽线程,以执行您想要的操作。然后他们将适当地更新数据库,您将不必在客户端做任何事情。
You may wish to interact with them from an admin point of view, hence you may have an MSMQ that they listen to admin commands on. Depending on your implementation, you may need to restart them for some reason, or possibly just 'force' a running of whatever they wish to do.
您可能希望从管理员的角度与他们进行交互,因此您可能有一个 MSMQ,他们可以监听管理员命令。根据您的实现,您可能出于某种原因需要重新启动它们,或者可能只是“强制”运行它们想做的任何事情。
So you'll use an MSMQ Private Queue to do it (System.Messaging namespace). One of the main things to note about MSMQ, is that message need to be < 4meg. So if you intend to send large object graphs, serialise to a file first and just send the filename.
因此,您将使用 MSMQ 专用队列来执行此操作(System.Messaging 命名空间)。关于 MSMQ 需要注意的主要事情之一是消息需要 < 4meg。因此,如果您打算发送大型对象图,请先将文件序列化并发送文件名。
MSMQ is quite beautiful. You can send based on a 'Correlation ID' if you need to, but, for some amusing reason, the correlation ID must be in the form of:
MSMQ 非常漂亮。如果需要,您可以根据“关联 ID”进行发送,但出于某种有趣的原因,关联 ID 必须采用以下形式:
{guid}
Anything else does not work (at least in version 2.0 of the framework, the code may have changed).
其他任何东西都不起作用(至少在框架的 2.0 版中,代码可能已更改)。
-- Edit
- 编辑
Example, as requested:
例如,根据要求:
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
回答by Adrian
Jeff has a great post showing how he achieved this originally for Stack Overflow at http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
Jeff 在http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/ 上发表了一篇很棒的文章,展示了他最初是如何为 Stack Overflow 实现这一目标的
While it might not be as reliable as a service if that's an option to you, it's served me well in the past for non essential tasks, and I've had it working in a virtual hosting environment.
如果您可以选择它,它可能不如服务那么可靠,但它过去在非必要任务中为我提供了很好的服务,而且我已经在虚拟主机环境中使用过它。
回答by Dhanuka777
Just found this question when searching for background process in ASP.NET MVC. (Available after .NET 4.5.2)
刚刚在 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);
}
Note: Personally I won't use the Webserver to run background tasks. Also don't reinvent the wheel, I would highly recommend to use Hangfire.
注意:我个人不会使用 Webserver 来运行后台任务。也不要重新发明轮子,我强烈建议使用Hangfire。
Read this great article from Hanselman HowToRunBackgroundTasksInASPNET
阅读 Hanselman HowToRunBackgroundTasksInASPNET 中的这篇精彩文章