【问题标题】:Async/Await vs TPL vs WCF Service vs Web API: So many choicesAsync/Await vs TPL vs WCF Service vs Web API:这么多选择
【发布时间】:2014-07-19 05:32:02
【问题描述】:

我的 ASP.Net 4 Web 应用程序调用了一些代码,这些代码为长时间运行的脚本生成了一个进程。读取标准输出并在数据库中更新返回值。我想“触发并忘记”这段代码,以便我的 UI 保持响应,并且用户不必等待这两个操作完成。调用代码不需要这两个操作的最终结果,所以我认为我不需要“等待”任何东西,也不需要任何成功或失败的指示。

我对所有可用选项感到困惑。编写此代码的最佳方法是什么,以便这两个操作以愉快的方式被发送出去并自己做他们的事情?

【问题讨论】:

标签: asp.net wcf asp.net-web-api task-parallel-library async-await


【解决方案1】:

我想“一劳永逸”这段代码

“一劳永逸”在 ASP.NET 上几乎总是错误的解决方案。

让我的 UI 保持响应式

您可以在不更改服务器端的情况下使您的 UI 具有响应性。只需异步执行请求(HttpClient 用于 .NET UI;AJAX 用于 HTML UI)。

我不需要任何成功或失败的迹象。

曾经?这就是我们通常会发现“一劳永逸”实际上并不是人们想要的。真正的“一劳永逸”意味着如果后台操作从未完成或出现错误,那么您完全可以,日志中不会显示任何内容。

正如我上面所说,最好的选择是在客户端处理“异步”需求。但是如果你真的需要在你的服务器上做,那么你有这三个选择:

  1. 添加具有独立后端的持久队列(例如,具有 Azure WebJob 的 Azure 队列)。您的 Web 应用程序只是将工作添加到队列中并返回。独立的后端从队列中读取数据并进行实际处理。
  2. 使用类似HangFire 的东西。这本质上是相同的,只是“队列”是一个数据库,并且后端与您的 ASP.NET 应用程序一起运行,而不是完全独立。
  3. 使用类似HostingEnvironment.QueueBackgroundWorkItem (.NET 4.5.2) 或我的AspNetBackgroundTasks (.NET 4.5) 的东西。这是一个更加危险的选择,因为没有可靠的存储空间。

【讨论】:

  • 我有一个很好的工作解决方案,它实现了一个任务来处理操作,但我担心也许我应该为此调用我的 Web API 接口。感谢您的意见。
【解决方案2】:

好吧,“最佳方式”可能值得商榷,但我会继续使用TPL,使用类似以下内容:

Task parentTask = Task.Factory.StartNew(() => SomeMethod(someParameter));

注意:如果“长时间运行的脚本”调用了 WCF 服务,那么下面关于 WCF 异步编程的文章可能会有所帮助。 http://blogs.msdn.com/b/wenlong/archive/2009/02/09/scale-wcf-application-better-with-asynchronous-programming.aspx

【讨论】:

  • 我只是想根据我的要求,会有一种设计方法比其他设计方法更好。如果我在描述中将术语“操作”替换为“任务”,我觉得 TPL 是要走的路。
  • 我在单个任务中封装的两个操作是触发 PowerShell 脚本以在 SCSM 中创建票证,然后使用返回的票证 ID 更新数据库。在我的测试环境中,这可能需要 15 秒到 2 分钟左右的时间。到目前为止,即使我“触发”任务并立即关闭浏览器,它也能正常工作。
  • 如果我理解正确,那么下面的文章可能会有用:stackoverflow.com/questions/17640575/…blogs.msdn.com/b/wmi/archive/2010/01/21/…
  • 感谢@Seymour 的链接。但我什至不需要等待手术的结果。我只需要异步触发它们。到目前为止,来自服务器端的 TPL 正在为我工​​作。
【解决方案3】:

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

WCFWeb API 是两个服务平台,可让您通过 服务 远程提供操作。

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

为了从您的 ASP.NET Web 执行这些服务操作的调用,您可以使用 TPL 等库,它为您提供异步 Tasksasyncawait 只是用于简化此类任务处理的 C# 关键字。

除了 TPL,您可以使用其他库和实现(例如线程)来执行调用,而不会阻塞您的 Web,但如今,任务是 .NET 中的首选方式。

如果您不太可能从不同的应用程序和长时间运行的进程中重复使用,或者不需要位于不同的机器上,您不妨直接将其作为任务实现,而不是经历所有的麻烦实现服务。

【讨论】:

  • 我想我想要么将代码保留在我当前的项目中但异步触发它,要么将其移动到服务并远程调用它(异步或非异步)。所以,你是对的,我好像在尝试比较不同的概念。
  • “不屏蔽你的网络”这到底是什么意思?
  • @svick OP 问题的上下文是“ASP.Net 4 web app”,所以这就是我所说的“你的 web”:如果长时间运行的进程让线程负责交付这样做的响应,它将“阻止网络”
猜你喜欢
  • 1970-01-01
  • 2020-12-31
  • 1970-01-01
  • 2018-10-09
  • 2012-11-02
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多