Web (asp.net) 环境中长时间运行的操作(线程)
我有一个 asp.net (mvc) 网站。作为功能的一部分,我必须支持一些长时间运行的操作,例如:
从用户启动: 用户可以将(xml)文件上传到服务器。在服务器上,我需要提取文件,进行一些操作(插入数据库)等...这可能需要一分钟到十分钟(甚至更多 - 取决于文件大小)。当然,我不想在导入运行时阻止请求,但我想将用户重定向到某个进度页面,在那里他将有机会查看状态、错误甚至取消导入。
该操作不会经常使用,但可能会出现两个用户同时尝试导入数据的情况。并行运行导入会很好。一开始我想在 iis (控制器操作)中创建一个新线程并在新线程中运行导入。但我不确定这是否是一个好主意(在网络服务器上创建工作线程)。我应该使用 Windows 服务还是任何其他方法?
从系统发起: - 我必须定期使用新数据更新 lucene 索引。 - 我将不得不发送大量电子邮件(将来)。
我应该将其实现为站点中的一项作业并通过 Quartz.net 运行该作业,还是还应该创建一个 Windows 服务或其他服务?
运行网站“作业”时的最佳实践是什么?
谢谢!
I have an asp.net (mvc) web site. As the part of the functions I will have to support some long running operations, for example:
Initiated from user:
User can upload (xml) file to the server. On the server I need to extract file, do some manipulation (insert into the db) etc... This can take from one minute to ten minutes (or even more - depends on file size). Of course I don't want to block the request when the import is running , but I want to redirect user to some progress page where he will have a chance to watch the status, errors or even cancel the import.
This operation will not be frequently used, but it may happen that two users at the same time will try to import the data. It would be nice to run the imports in parallel. At the beginning I was thinking to create a new thread in the iis (controller action) and run the import in a new thread. But I am not sure if this is a good idea (to create working threads on a web server). Should I use windows services or any other approach?
Initiated from system:
- I will have to periodically update lucene index with the new data.
- I will have to send mass emails (in the future).
Should I implement this as a job in the site and run the job via Quartz.net or should I also create a windows service or something?
What are the best practices when it comes to running site "jobs"?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我将为长时间运行的任务实现独立的 Windows 服务。 Web 应用程序通过队列方法将长时间运行的任务委托给该服务。如何组织任务队列取决于您。排队任务是否有优先级、最大执行时间。队列可以作为 DBMS 中的普通表来实现,其中包含作业执行状态信息属性(非常简单的方法)。
因此,常见的场景可能如下所示:
客户端将所有必需的信息发送到 Web 服务器
Web 服务器将任务委托给服务
并通知客户 - 任务是
成功排队(任务 ID 也发送到客户端)
外部服务开始任务处理,
更新进度信息。
客户端开始轮询 Web 服务器
关于作业的简短执行请求(带有之前收到的 ID)
状态和进度。
您可以选择不同的技术(Windows 服务 + DB / WCF 服务)和不同的通信方法(轮询、推送、回调),但我建议将长时间运行的任务委托给外部服务(不要在 Web 应用程序中执行它们)。
执行长时间运行的任务带来了每个请求一个线程的模型(用多线程编程术语来说)。该模型可扩展性较差,且线程池最大线程数有限制。但这不是你的情况:)
I would implement stand-alone windows service for long running tasks. Web application delegates long-running tasks to this service via queue approach. It's up to you how you will organize tasks queue. Will queued task have priority, maximum execution time or not. Queue can be implemented as ordinary table(s) in DBMS, that contains job execution status info properties (pretty straightforward approach).
So common scenario may look the following:
Client sends all required information to web-server
Web-server delegates task to service
and notifies client - task was
successfully queued (task id is sent to client also)
External service starts task processing,
updating progress information.
Client starts polling web server with
short execution requests about job (with id received earlier)
status and progress.
You can choose different technologies (Windows Service + DB / WCF Service) and different communication approaches (polling, pushing, callbacks) but I advise to delegate long-running tasks to external service (not perform them within web app).
Executing long running tasks brings thread-per-request model (in multithreaded programming terms). This model has poor scalability and thread pool maximum number of threads limitations. It's not your case though :)
在我看来,长时间运行的任务通常应该委托给非基于 UI 的操作。我建议也许使用 WF 或 Window 服务。
In my opinion long running tasks should generally always be delegated to non UI based operations. I would suggest perhaps a WF or Window service.
我已经使用 jQuery 成功实现了与此类似的场景。基本上,我使用
beforeSend
: 函数来显示“请稍候”类型的页面。这是正在运行的基本代码(但我不知道,您也可以使用AsyncController
基类来使操作异步):希望这会有所帮助。
SendAjax
方法纯粹是一个包装函数,可以使事情更加一致。这里是完整的:[编辑] - 不确定 SendAjax 格式发生了什么。希望很容易复制/粘贴......
I've successfully implemented a scenario similar to this using jQuery. basically, i use the
beforeSend
: function to display the 'please wait' type page. here's the basic code in play (altso i don't, you could also use theAsyncController
base class to make the action async):hope this helps.
the
SendAjax
method is purely a wrapper function to make things a little more consistant. here it is in full:[edit] - not sure what's happening with the SendAjax formatting. hope it's easy to copy/paste out...