【问题标题】:WCF Fire Async Task (Fire and forget style) - Resource concernsWCF Fire Async Task (Fire and forget style) - 资源问题
【发布时间】:2013-11-08 01:52:42
【问题描述】:

我们有一个 ASP.NET MVC 3 应用程序,它与 WCF 层交互以实现服务逻辑。在一项特定功能上,服务层需要很长时间才能响应,即 svc 上的 UI 超时处理本身是巨大的,因此必然需要更多时间。我们不希望用户看到超时因此我们计划显示部分成功状态并不断更新 UI 状态。

我们计划将流程分成多个步骤,其中一些步骤有点一劳永逸。现在当用户请求详细信息时

  1. Svc 处理强制步骤,返回响应

  2. Svc 还使用以下 (TPL) 启动任务触发它,这会执行 非强制性步骤

    Task.Factory.StartNew(FireAway);
    
  3. UI 不断轮询更新状态

  4. 任务在数据库中更新完成状态

  5. UI 轮询和检索完成状态并在 UI 中显示

担忧...

  1. 处理任务的线程是否会被重用(未附加侦听器),这会导致线程创建过多或泄漏吗?
  2. 资源怎么样,Fire and forget tasks 会导致内存泄漏吗?任务功能是连接到多个数据库并更新状态。
  3. 我对设计不满意(我们必须尽快解决),还有更好的设计模式吗?

【问题讨论】:

  • 来吧,伙计们,还没有回应....问题这么无聊吗?
  • 我认为您没有向我们提供足够的信息来回答您的问题。是否发生泄漏取决于您的具体代码。
  • 哎呀,我详细地添加了解释。关于泄漏的问题通常是 Fire and Forget 任务会产生任何泄漏?任务主要是更新数据库并连接到不同的系统。我更新了问题
  • 任何关于它的示例代码,用于调用 WCF 服务(即发即弃)和错误处理?

标签: c# asp.net-mvc-3 wcf asynchronous task-parallel-library


【解决方案1】:

Marcin 是正确的。我赞成这个答案,但认为我应该解释一下。 TPL 本身不会导致资源泄漏。如果您遇到任何资源泄漏,请阅读this article。 :-)

Marcin 关于 IIS 回收 AppPool 并导致“数据丢失”的可能性也是正确的。我们有一个类似的场景,发现这种情况发生的频率比人们想象的要多。我们稍微重新设计了我们的服务,以接收一个触发器消息,通知它“嘿,你有一些数据在数据库中等着你。”这消除了轮询的需要。执行的功能是一个多步骤过程,每个步骤都会更新数据库,以便如果服务在中途重新启动/回收,它可以从中断的地方继续。您需要将其转换为 Windows 服务,但如果您希望或需要将其移动到不同的非 Web 服务器,您可以这样做。

如果您担心线程过多,请查看this SO Q&A

教学说明:异步和即发即弃是不一样的。异步的意思是“我想要一个答案,但等不及了,等你完成后给我打电话。” Fire-and-forget 的意思是“这里有一些数据/信息。你可以用它做什么,但不要打电话给我。我不在乎,否则我会稍后再打给我,如果我想知道的话。”

【讨论】:

  • 我喜欢你的触发消息方法。
【解决方案2】:

首先创建

Task.Factory.StartNew(FireAway);

您没有明确创建新线程。该任务将使用线程池中的线程,但没有从任务到线程的 1:1 映射。例如,如果您的任务将花费很长时间进行 I/O 操作,则底层线程可以被另一个请求使用。

您指定的设计不应导致任何资源(线程或内存)泄漏,前提是您已正确完成所有操作。从技术角度来看,设计是正确的,但可以大大改进。

这种设计很容易导致 IIS 在运行过程中重新启动而终止该任务。更好的方法是让您的 Web 请求将请求信息存储在数据库中,并让后端的一些 Windows 服务获取并处理它。 UI 可以简单地检查数据库以获取给定任务的更新。

【讨论】:

  • "如果您的任务将花费很长时间进行 I/O 操作,则底层线程可以被另一个请求使用" 假设这些是同步 IO 操作,那就错了。阻塞ThreadPool 线程只会阻塞该线程,.Net 没有任何聪明的方法可以在阻塞时释放线程。
猜你喜欢
  • 2020-03-05
  • 2014-05-16
  • 1970-01-01
  • 2019-07-07
  • 2013-01-13
  • 2021-10-12
  • 2017-02-19
  • 1970-01-01
  • 2023-02-25
相关资源
最近更新 更多