Windows Workflow Runtime泄露了大量的内存。

3

以下是我的工作流程实现概述:

  • GUI线程启动工作线程
  • 工作线程分析一些数据
  • 工作线程启动几个其他工作线程来处理数据的子集
  • 每个最后的工作线程创建一个工作流运行时并执行顺序工作流

到目前为止,我一直像这样在每个线程中创建一个新的WorkflowRuntime对象:

  using( WorkflowRuntime workflow_runtime = new WorkflowRuntime()) {
      AutoResetEvent waitHandle = new AutoResetEvent(false);
      workflow_runtime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
      workflow_runtime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
      {
          Console.WriteLine(e.Exception.Message);
          waitHandle.Set();
      };

      WorkflowInstance instance = workflow_runtime.CreateWorkflow(typeof(MyWorkflow), parameters);
      instance.Start();
      waitHandle.WaitOne();
}

这样做的原因是我需要知道特定工作流实例何时终止或出错。问题是它会导致我的应用程序出现巨大的内存泄漏,如在这里SO上所述。
如果我使用using关键字,甚至如果我调用Dispose并将workflow_runtime引用设置为null,我都会遇到严重的内存泄漏问题。然而,如果我将工作流运行时实现为单例模式,如此帖子中所述,内存使用率非常低且稳定。我可以通过图表中的闪烁看到工作流何时启动和完成。
问题是,如果我为WF运行时使用单例模式,我如何知道特定工作流是否出错?如果我只是注册事件处理程序,当任何一个工作流终止或完成时,不是所有事件处理程序都会被调用吗?
编辑:我应该只是在堆栈上使用另一个句柄来处理错误,然后等待其中一个被设置,然后检查哪一个被设置?我以前应该考虑过这个问题。

1
你尝试过注销 WorkflowCompleted 和 WorkflowTerminated 事件吗? - overslacked
我敢打赌你说得一点也没错。我一直在使用网络上泛滥的工作流程代码,但它存在缺陷,因为它使用了一种防止事件处理程序注销的方法!我现在会尝试一下,并且如果你在这里发布答案,我会将其标记为答案。感谢你发现了这个愚蠢的错误。 - Dave
这篇文章不仅展示了一个注销处理程序的好方法,还向我展示了如何处理我问题的另一部分——如何区分工作流程!http://bit.ly/8pkEWT - Dave
我猜我得出了结论。我注销了事件处理程序(我设置断点以确认它正在发生),但仍然存在内存泄漏。很奇怪。 - Dave
1个回答

2
所以这就是我决定解决问题的方法。如果我的解决方案有问题,请发表评论,我会标记其他人的答案,如果正确。
我更改了代码来注销之前帖子中的事件处理程序,并通过设置断点确认了代码正在执行。运行应用程序后,仍然泄漏1.5GB。
我对单例模式的一个问题是我不知道如何处理工作流的不同实例。结果,我只需要检查通过事件参数传递的InstanceID并确保它们匹配即可。这就是您处理不同工作流事件的方式。
我从http://bit.ly/8pkEWT实现了单例模式,并且除此之外,注销了事件处理程序并处理了InstanceIDs。内存泄漏已经消失了!但是,我还没有验证每个工作流的结果。(天哪)

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