我使用 ASP.Net MVC 5 并且我有一个长时间运行的操作,它必须轮询 Web 服务、处理数据并将它们存储在数据库中。
为此,我想使用 TPL 库来异步启动任务。
但我想知道如何做三件事:
- 我想报告此任务的进度。为此,我考虑 SignalR
- 我希望能够离开我开始执行此任务的页面,并能够报告整个网站的进度(从左侧的面板,但这没关系)
- 我希望能够全局取消这个任务(从我左边的面板)
我对所涉及的所有技术都了解不少。但我不确定实现这一目标的最佳方法。
有人可以帮助我了解最佳解决方案吗?
我使用 ASP.Net MVC 5 并且我有一个长时间运行的操作,它必须轮询 Web 服务、处理数据并将它们存储在数据库中。
为此,我想使用 TPL 库来异步启动任务。
但我想知道如何做三件事:
我对所涉及的所有技术都了解不少。但我不确定实现这一目标的最佳方法。
有人可以帮助我了解最佳解决方案吗?
您想要运行长时间运行的工作,而用户可以离开启动工作的页面,这意味着您需要“在后台”运行这项工作。它不能作为常规 HTTP 请求的一部分执行,因为用户可能随时通过导航或关闭浏览器来取消他的请求。事实上,这对你来说似乎是一个关键场景。
ASP.NET 中的后台工作很危险。你当然可以成功,但要做到正确并不容易。此外,工作进程可能因多种原因退出(应用程序池回收、部署、机器重启、机器故障、堆栈溢出或无关线程上的 OOM 异常)。因此,请确保您的长期工作能够容忍中途中断。您可以减少发生这种情况的可能性,但永远不要排除这种可能性。
您可以通过将所有工作包装在事务中来使您的代码在任意终止时安全。当然,这仅在您不引起非事务性副作用(例如更改状态的 Web 服务调用)时才有效。在这里不可能给出一个一般性的答案,因为在存在任意终止的情况下实现安全性在很大程度上取决于要完成的具体工作。
这是我过去使用过的一种可能的架构:
也许您可以使用消息队列来处理作业,但我总是很谨慎地使用它。要以事务处理方式处理消息,您需要 MSDTC,许多 SQL Server 的高可用性解决方案都不支持它。
您可能认为这种架构不是很复杂。它利用轮询来处理很多事情。轮询是一种原始技术,但效果很好。它可靠且易于理解。它有一个简单的并发模型。
如果您可以假设您的应用程序永远不会在不合时宜的时间退出,那么架构会简单得多。但这不能假设。您不能假设在工作时间内不会进行部署,并且不会存在导致崩溃的错误。
即使使用 http worker 对运行长任务来说是一件坏事,我也做了一个小例子来说明如何使用 SignalR 管理它:
在此示例中,您可以:
它基于:
您可以在此处找到此示例的来源: