异步/等待 vs TPL vs WCF服务 vs Web API: 选择太多了

4
我的ASP.Net 4网站调用了一些代码,以产生一个长时间运行的脚本进程。标准输出被读取,返回值被更新到数据库中。我希望"启动并忘记"这段代码,以便我的UI保持响应,并且用户不必等待这两个操作完成。这两个操作的最终结果不需要由调用代码处理,所以我认为我不需要"等待"任何东西,也不需要任何成功或失败的指示。
我对所有可用的选项感到困惑。最好的编码方式是什么,使这两个操作只需自己独立地执行它们的任务?

请注意在IIS主机中长时间运行任务的危险性: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/ - Frode
3个回答

3
我想要“点火并忘记”这段代码。
在ASP.NET中,“点火并忘记”几乎总是错误的解决方案。
这样我的UI仍然可以响应。
您可以在不改变服务器端的情况下使UI响应。只需异步执行请求(.NET UI使用HttpClient;HTML UI使用AJAX)。
我不需要任何成功或失败的指示。
从来吗?这通常是我们发现“点火并忘记”实际上并不是人们想要的地方。真正的“点火并忘记”意味着如果后台操作永远不完成或出现错误,那么您完全可以接受日志中没有任何内容。
如上所述,最好的选择是在客户端处理“异步”要求。但是,如果您确实需要在服务器上执行此操作,则有以下三个选项:
  1. 添加一个具有独立后端(例如,使用Azure WebJob的Azure队列)的持久队列。你的Web应用程序只需将工作任务添加到队列中并返回。独立后端从队列中读取并执行实际处理。
  2. 使用类似于 HangFire 的东西。这本质上是相同的,除了“队列”是数据库并且后端与您的ASP.NET应用程序一起运行,而不是完全独立的。
  3. 使用类似于 HostingEnvironment.QueueBackgroundWorkItem (.NET 4.5.2) 或我的AspNetBackgroundTasks (.NET 4.5)。这是一个更加危险的选择,因为没有可靠的存储工作。

我已经有一个很好的工作解决方案,实现了一个单一的任务来处理操作,但我担心也许我应该调用我的Web API接口来完成这个任务。谢谢你的意见。 - beaudetious

2

我就觉得基于我的需求,应该有一种最好的设计方法。如果我在我的描述中将“操作”替换为“任务”,那么我觉得TPL是最合适的选择。 - beaudetious
我将两个操作封装在一个单独的任务中,即触发一个 PowerShell 脚本创建 SCSM 中的工单,然后使用返回的工单 ID 更新数据库。在我的测试环境中,这可能需要 15 秒到 2 分钟左右的时间。到目前为止,它甚至可以在我“触发”任务并立即关闭浏览器的情况下正常工作。 - beaudetious
如果我理解正确的话,那么以下文章可能会有用:https://dev59.com/WWMm5IYBdhLWcg3wZ-XQ 和 http://blogs.msdn.com/b/wmi/archive/2010/01/21/perform-asynchronous-asset-management-using-windows-powershell-cmdlets-for-wmi.aspx - Seymour
谢谢你分享链接,@Seymour。但我甚至不需要等待操作结果,只需要异步地发起它们。到目前为止,服务器端的TPL对我很有效。 - beaudetious

2

我认为你混淆了一些术语。

WCFWeb API 是两种服务平台,可以通过服务远程提供操作。

使用任何一种技术,这些公开的操作都可以同步或异步实现,但即使您选择异步实现,调用此类操作的时间可能会有很大的延迟,因此应该异步调用。

为了从您的ASP.NET Web执行这些服务操作的调用,您可以使用诸如TPL之类的库,它提供了异步的Tasksasyncawait只是C#关键字,以便更轻松地处理此类任务。

除了TPL之外,您还可以使用其他库和实现,例如线程来执行调用而不阻止您的Web,但在.NET中,Tasks是首选的方式。

如果您不太可能从不同的应用程序重用,并且您的长时间运行的进程或不需要位于不同的计算机上,则可以将其直接实现为Task,而不必经过实施服务的所有麻烦。


我想要么将代码保留在我的当前项目中,但异步地执行它,要么将其移到服务中并远程调用(无论是否异步)。所以,你是正确的,看起来我试图比较不同的概念。 - beaudetious
2
“不阻塞您的网站” 这是什么意思? - svick
@svick OP问题的背景是“ASP.Net 4 Web应用程序”,所以我提到的“你的Web”指的就是这个:如果长时间运行的进程阻止了负责传递响应的线程,那么它将“阻塞Web”。 - jnovo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接