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.