04-02-2014 09:34 AM
I am creating a TestStand sequence file and sequences in C#.
After I released the sequence file and shut down the engine I get a warning:
'References to PropertyObjects were not released properly.' The complete warning is attached at the end of the message.
My code is about this:
MyEngine = new EngineClass();
MyEngine.LoadTypePaletteFilesEx(TypeConflictHandlerTypes.ConflictHandler_Error, 0);
SequenceFile TS_SequenceLib MyEngine.GetSequenceFileEx(libfilepath, 0, TypeConflictHandlerTypes.ConflictHandler_Error);
//create a new sequence file
SequenceFile seqFile = MyEngine.NewSequenceFile();
//create and insert some sequences and save the sequence file
seqFile.Save(path);
After finshed inserting the sequences I release both sequence files
seqFile.UnloadModules();
MyEngine.ReleaseSequenceFileEx(seqFile);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(seqFile);
seqFile = null;
I do the same with the other sequencefile TS_SequenceLib and shut down the engine:
MyEngine.UnloadTypePaletteFiles();
MyEngine.UnloadAllModules();
MyEngine.ShutDown(true);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(MyEngine);
MyEngine = null;
I tried to iterate through the sequences of each sequence file and remove and release each sequence but it didn't help.
How shoud I release the sequence files, the sequences and the other objects properly to get rid of the warning?
Here is the entire warning:
References to PropertyObjects were not released properly.
Total number of objects: 44310
Number of top-level objects: 248
Note: Some top-level objects may be included if they are referenced by
an incorrectly released top-level object. For example, an unreleased
SequenceContext object references a SequenceFile object.
The following top-level objects were not released:
Sequences [62 object(s) not released]
Sequence #1:
Name: XXXXX_Output_Sensory
Sequence #2:
Name: MainSequence
Sequence #3:
Name: XXXXX_Output_Diagnostic
Sequence #4:
Name: MainSequence
Sequence #5:
Name: XXXXX_Output_Optic
Sequence #6:
Name: MainSequence
Sequence #7:
Name: XXXXX_Output_Acoustic
Sequence #8:
Name: MainSequence
Sequence #9:
Name: XXXXX_Copy_of_Output_CAN_missing_message
Sequence #10:
Name: MainSequence
Sequence #11:
Name: XXXXX_Output_CAN_complete
Sequence #12:
Name: MainSequence
Sequence #13:
Name: XXXXX_Input_Sensory
Sequence #14:
Name: MainSequence
Sequence #15:
Name: XXXXX_Input_Diagnostic
Sequence #16:
Name: MainSequence
Sequence #17:
Name: XXXXX_Input_Haptic_external
Sequence #18:
Name: MainSequence
Sequence #19:
Name: XXXXX_Input_Acoustic
Sequence #20:
Name: MainSequence
Sequence #21:
Name: XXXXX_Input_CAN_missing_message
Sequence #22:
Name: MainSequence
Sequence #23:
Name: XXXXX_Input_CAN_complete
Sequence #24:
Name: MainSequence
Sequence #25:
Name: XXXXX_Input_CCC
Sequence #26:
Name: MainSequence
Sequence #27:
Name: XXXXX_FlowControl_Ramp_IncrementByTime
Sequence #28:
Name: MainSequence
Sequence #29:
Name: XXXXX_FlowControl_Ramp_IncrementBy1
Sequence #30:
Name: MainSequence
Sequence #31:
Name: XXXXX_FlowControl_Loop_TimeControlled
Sequence #32:
Name: MainSequence
Sequence #33:
Name: XXXXX_FlowControl_Loop_Cycles
Sequence #34:
Name: MainSequence
Sequence #35:
Name: Par0_thread3
Sequence #36:
Name: Par0_thread2
Sequence #37:
Name: Par0_thread1
Sequence #38:
Name: Par0_thread0
Sequence #39:
Name: XXXXX_FlowControl_Parallel
Sequence #40:
Name: MainSequence
Sequence #41:
Name: XXXXX_FlowControl_TimeRequirement_WaitAtleast
Sequence #42:
Name: MainSequence
Sequence #43:
Name: XXXXX_FlowControl_TimeRequirement_WaitExactly
Sequence #44:
Name: MainSequence
Sequence #45:
Name: XXXXX_FlowControl_TimeRequirement_Within
Sequence #46:
Name: MainSequence
Sequence #47:
Name: MainSequence
Sequence #48:
Name: Flow_Wait
Sequence #49:
Name: Act_HapticIn
Sequence #50:
Name: Act_ReactionOut
Sequence #51:
Name: Act_SensoryOut
Sequence #52:
Name: Act_DiagnosticOut
Sequence #53:
Name: Act_OpticOut
Sequence #54:
Name: Act_AcousticOut
Sequence #55:
Name: Act_SensoryIn
Sequence #56:
Name: Act_DiagnosticIn
Sequence #57:
Name: Act_AcousticIn
Sequence #58:
Name: Act_CCCIn
Sequence #59:
Name: Act_CANOut
Sequence #60:
Name: Flow_Parallel
Sequence #61:
Name: Act_CANIn
Sequence #62:
Name: MainSequence
Type Definitions [44 object(s) not released]
Type Definition #1:
Name: OpenModelManager
Type Definition #2:
Name: AdditionalResults
Type Definition #3:
Name: Goto
Type Definition #4:
Name: Label
Type Definition #5:
Name: Statement
Type Definition #6:
Name: SequenceCall
Type Definition #7:
Name: NI_Wait
Type Definition #8:
Name: NI_Flow_End
...
Note: More objects were not released, but not listed.
04-02-2014 09:52 AM
It looks like the message is specifically about sequences rather than sequence files. Could you post a snippet of the code where you're adding new sequences to the sequence file? It's possible that a reference in that section of the code needs to be closed in order to resolve the error message.
04-02-2014 10:33 AM - edited 04-02-2014 10:36 AM
A couple issues:
1) You are calling GetSequenceFileEx() and storing the reference in TS_SequenceLib, but you are never calling ReleaseSequenceFileEx() on it and are never calling Marshal.FinalReleaseComObject() on it.
2) Rather than calling:
Marshal.FinalReleaseComObject()
Before exiting, just set all references other than the engine to null (or write your code such that those references are no longer in scope). Then, before the engine reference goes out of scope, do the following:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
// You have to do the GC.Collect() and GC.WaitForPendingFinalizers() calls twice to ensure all objects pending for garbage collection are destroyed due to how .NET does garbage collection.
Or call the function DoSynchronousGCForCOMObjectDestruction() in the <TestStand>\API\DotNet\Assemblies\CurrentVersion\NationalInstruments.TestStand.Utility.dll assembly.
This will ensure that the engine is deleted last and thus its leak detection code won't report any leaks due to objects being held onto for garbage collection.
Trying to call Marshal.FinalReleaseComObject or Marshal.ReleaseComObject() on every reference is a lot more trouble and not really necessary if you just force garabage collection before the engine is destroyed.
There are other places you might want to force garbage collection, such as when a sequence file or execution is closed to ensure a more timely execution of Unload callbacks, but if you aren't using any unload callbacks or you are disabling them then this isn't necessary.
Hope this helps,
-Doug
04-03-2014 12:28 AM
04-03-2014 03:54 AM
Hi,
thank you for the quick answers!
1) I am calling GetSequenceFileEx() and Marshal.FinalReleaseComObject() for TS_SequenceLib. I only mentioned,
that I release both sequence files but I don't inserted the code snippet twice.
2) I tried to call GC.Collect() and GC.WaitForPendingFinalizers(); and I also tried DoSynchronousGCForCOMObjectDestruction()
but it didn't help.
I have attached the code snippet in which I create the sequences. This happens in separate function, so I thought,
the references to the sequences are out of scope after returning back to the main function but it seems that they are still existing.
How should I release the sequences?
I have tried FinalReleaseComObject(seq) and seqFile.RemoveSequence(i).
Should I close the sequence file, if yes how?
Thank you for the help.
The code snippet how I create the sequences:
//create the sequence
seq = MyEngine.NewSequence();
seq.Name = tcName;
//create a step
step = Create_newStep("SequenceCall", "OpticOut", child.GetAttribute("Target") + comment); //child is an XmlElement
SequenceCallModule mod = (SequenceCallModule)step.Module;
//set some mod.Parameters
//identify index of the step
//insert the step to the sequence
seq.InsertStep(step, index, StepGroups.StepGroup_Main);
seqFile.InsertSequenceEx(0, seq);
private Step Create_newStep(string type, string name, string comment)
{
Step step = MyEngine.NewStep("", type);
step.Name = name;
step.AsPropertyObject().Comment = comment;
NationalInstruments.TestStand.Interop.API.Sequence seq = TS_SequenceLib.GetSequenceByName("Act_CANIn");
SequenceCallModule objModule = (SequenceCallModule)step.Module;
objModule.SequenceName = "Act_" + name;
objModule.UseSequenceParameterPrototype = false;
//objModule.LoadParametersFromSequence(seq);
objModule.SequenceFilePath = "MM_SpecEdit_Lib.seq";
objModule.LoadPrototypeFromSequence(seq, 0);
objModule.UseSequenceParameterPrototype = true;
return step;
}
04-03-2014 07:29 AM