Windows 工作流运行时泄漏大量内存
以下是我的工作流程实现的概述:
- 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();
}
这样做的原因是我需要知道特定工作流程实例何时终止或出错。问题是它会导致我的应用程序中出现巨大的内存泄漏,正如此处提到的< /a>.
如果我使用 using 关键字,或者即使我调用 Dispose 并将工作流程运行时引用设置为 null,也会出现大量内存泄漏。但是,如果我将工作流运行时实现为单例,如本文所述,内存使用率非常低且一致。我可以通过图中的提示看到工作流程何时启动和完成。
问题是,如果我对 WF 运行时使用单例模式,我如何知道特定工作流程何时出现错误?如果我只注册事件处理程序,当任何工作流程终止或完成时,是否会调用所有事件处理程序?
编辑:我是否应该使用堆栈上的另一个句柄来处理错误,然后等待其中一个句柄被设置,然后检查设置了哪一个?我之前就应该考虑到这一点。
Here's a overview of my workflow implementation:
- GUI thread starts worker thread
- worker thread analyzes some data
- worker thread starts several other worker threads to work on subsets of
data - each of these last worker threads creates a workflow runtime and
executes a sequential workflow
Up until now, I've been creating a new WorkflowRuntime object in each thread like this:
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();
}
The reason for doing it this way is that I need to know when a specific workflow instance has been terminated or errored. The problem is that it causes a huge memory leak in my application, as mentioned here on SO.
If I use the using keyword, or even if I call Dispose and set the workflow_runtime reference to null, I get a massive memory leak. However, if I implement the workflow runtime as a Singleton, as described in this post, memory usage is very low and consistent. I can see when workflows are launched and completed by blips in the graph.
The problem is, if I use the Singleton pattern for the WF runtime, how will I know when a specific workflow has an error? If I just register the event handlers, won't all of them get called when any of the workflows get terminated or completed?
EDIT: should I just use another handle on the stack for errors, and then wait for either to be set, and then check which one was set? I should have considered that before.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以这就是我决定解决这个问题的方法。如果我的解决方案有问题,请发表评论,如果正确的话我会标记其他人的答案。
我在上一篇文章中更改了代码以注销事件处理程序,并通过设置断点确认代码正在执行。运行应用程序后,仍然泄漏 1.5GB。
我对单例模式的问题之一是我不知道如何处理工作流程的不同实例。事实证明,我只需检查通过事件参数传递的实例的 InstanceID 并确保它们匹配。这就是处理不同工作流程事件的方式。
我从 http://bit.ly/8pkEWT 实现了单例模式,此外,还取消注册了事件处理程序和处理 InstanceID。内存泄漏消失了!但是,我还没有抽出时间来验证每个工作流程的结果。 (哎呀)
So here is how I have decided to solve the problem. If there is something wrong with my solution, please post comments and I will mark someone else's answer instead, if it's correct.
I changed the code to unregister the event handlers in my previous post, and confirmed that the code was executing by setting breakpoints. After running the application, it still leaked 1.5GB.
One of my issues with the Singleton pattern is that I didn't know how to handle different instances of the workflows. It turns out that I just had to check the InstanceID of the Instance passed through the event args and make sure they matched. This is how you deal with disparate workflow events.
I implemented the Singleton pattern from http://bit.ly/8pkEWT and in addition, unregistered the event handlers and handled the InstanceIDs. The memory leak is gone! However, I haven't gotten around to validating the results of each workflow. (yikes)