WCF Fire异步任务(火灾和遗忘风格) - 资源问题

时间:2013-10-29 03:43:49

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

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

我们计划将流程分为不同的步骤,其中一些步骤是 fire and forget fashion 。现在当用户请求细节时

  1. Svc处理强制性步骤,返回回复

  2. Svc还启动一个任务使用下面的(TPL)触发它,执行非强制性步骤

    Task.Factory.StartNew(FireAway);
    
  3. 用户界面保持轮询以更新状态

  4. 任务更新DB中的完成状态

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

  6. 关注...

    1. 处理任务的线程是否会被重用(没有附加侦听器),这是否会导致线程创建或泄漏过多?
    2. 资源如何,火灾和忘记任务会导致内存泄漏?任务功能是连接到多个DB并更新状态。
    3. 我对设计不满意(我们必须做快速修复),还有更好的设计模式?

2 个答案:

答案 0 :(得分:1)

首先创建

Task.Factory.StartNew(FireAway);

您没有显式创建新线程。该任务将使用线程池中的线程,但是从任务到线程没有1:1的映射。例如,如果您的任务将花费很长时间来执行I / O操作,那么基础线程可以被另一个请求使用。

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

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

答案 1 :(得分:1)

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

Marcin对于IIS回收AppPool并导致“数据丢失”的可能性也是正确的。我们有类似的情况,发现发生的次数比人们想象的要多。我们稍微重新设计了我们的服务以接收触发器消息,告知它“嘿,你有一些数据在数据库中等着你。”这消除了轮询的需要。执行的功能是一个多步骤过程,每个步骤都会更新数据库,这样如果服务在中途重新启动/回收,它就可以从停止的位置进行拾取。您不需要将其转换为Windows服务,但如果您想要或需要将其移动到其他非Web服务器,则可以。

如果您担心假脱机太多线程,请查看this SO Q&A

教学说明:异步和即发即弃不一样。异步意味着“我想要一个答案,但不能等待,所以一旦你完成,请稍后再打电话给我。” “一劳永逸”的意思是“这里有一些数据/信息。做你用它做什么,但不要打电话给我。我不在乎,或者如果我想知道,我会稍后回电。”