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