I am trying to implement a workflow designer in a windows form application and use the same designer to view different workflows. However, I found the program became slower and slower after loading several workflows.
my steps are as follows:
1. Create a WPF user control to package the workflowdesigner.
2. In the user control, create a new workflowDesigner instance each time when called. I suppose the old workflowDesigner instance would be collected by GC.
3. Create a Winform control and install the WPF user control created on step 2 into an element host, and put the element host on the winform userControl.
4. Load Winform user control created in stpe 3 into a Tab inside a Winform application.
5. Using a button to launch and close the tab.
The result: First time when I launch the tab it consumes around 30MB of space (may be due to first time WPF assembly load), from next time onwards it takes 13MB in each launch and after 30-40 launch attempts memory consumption become large enough to me make application too slow.
I am disposing following objects explicitly:
private void InitializeWorkflowDesigner()
workflowDesigner = new WorkflowDesigner();
workflowDesigner.Context.Items.GetValue<ReadOnlyState>().IsReadOnly = true;
workflowDesigner.View.PreviewMouseDown += OnPreviewMouseDown;
attachPropertyRecord = new AttachedProperty<ActivityStateRecord>
Name = "Record",
Setter = (modelItem, tracingRecord) => modelItemMapping.SetRecordValue(modelItem, tracingRecord), // modelItemMapping is a class which provide mappings.
Getter = modelItem => modelItemMapping.GetRecordValue(modelItem),
OwnerType = typeof(Activity)
grid.Children.Add(workflowDesigner.View); // grid is Grid of WPF control.
var modelService = workflowDesigner.Context.Services.GetService<ModelService>();
sourceLocationProvider = new SourceLocationProvider(
var designerView = workflowDesigner.Context.Services.GetService<DesignerView>();
if (designerView != null)
designerView.WorkflowShellBarItemVisibility = // ShellBarItemVisibility.Imports |
ShellBarItemVisibility.MiniMap | // ShellBarItemVisibility.Variables |
// ShellBarItemVisibility.Arguments | <-- Uncomment to show again
/// Method which we call inside "SourceLocationProvider" constructor.
private void UpdateSourceLocationMappingInDebuggerService(string workflowFilePath, DebuggerService debuggerService, string loadedFile, object rootInstance)
workflowElementToSourceLocationMap = new Dictionary<object, SourceLocation>();
designerSourceLocationMapping = new Dictionary<object, SourceLocation>();
if (rootInstance != null)
Activity documentRootElement = GetRootWorkflowElement(rootInstance);
// Collect the mapping between the Model Item tree and its underlying source location
// Notify the DebuggerService of the new sourceLocationMapping.
// When rootInstance == null, it'll just reset the mapping.
// DebuggerService debuggerService = debuggerService as DebuggerService;
if (debuggerService != null)