2

我们有一个 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. 我对设计不满意(我们必须这样做作为快速修复),还有更好的设计模式吗?
4

2 回答 2

1

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

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

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

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

于 2013-11-27T14:18:11.500 回答
1

首先通过创建

Task.Factory.StartNew(FireAway);

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

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

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

于 2013-10-29T09:43:33.807 回答