NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Reload sequence file when changes on disk

Hi,

I wrote a custom user interface based on the TestStand (TS) Operator Interface. When I run a sequence file on it and I edit it in the TS editor and I restart an execution, it seems to keep loading the first one when I launch the execution. The only way I can do this is by restarting the GUI.


I read a lot and tried many things and I can’t figure out what do I need to do to have the sequence file reload from disk on the 2nd execution after changes has been made.


I tried many thing and it seems to work when I release the seq file 2 times (!). But, as expected, the 2nd time it get released, I get an error that the file was unloaded from the TestStand Engine. And the weird thing is that I don’t get the error when I run the 1st time or I don’t make changes to the seq file.


Do you see anything wrong? Or have another suggestion how I could achieve that?

Can I see which seq files are in the internal cache? That could be useful to debug.

Thank you.

A code snippet in C# is in attachement.
0 Kudos
Message 1 of 9
(4,586 Views)

Are you starting the TestStand sequence editor separately from the operator interface or are you changing the operator interface to an editor with CTL-ALT-SHIFT-INSERT?

 

edit- that's the keystrokes for the LabVIEW OI. Don't know if the others work the same way.

Message Edited by Dennis Knutson on 02-24-2010 05:58 PM
0 Kudos
Message 2 of 9
(4,584 Views)

You probably need to do a PropertObjectFile.IncChangeCount to signal UI that your SequenceFile has changed.

 

Regards

Ray Farmer

Regards
Ray Farmer
0 Kudos
Message 3 of 9
(4,564 Views)

I don't edit the sequence file in the OI.

It is done with the TestStand Sequence Editor. I could copy-paste a new version of the file to overwrite the current one on disk, I think it would be similar.

 

If you look at the code that runs everytime I use the Start Test button, the sequence file is reloaded to be launch. The 1st time from disk, and the other times from the memory. I would like NOT to load it from memory when the seq File is different on disk then from the memory.

 

The only way it seems to work is when I release it 2 times but it causes an error on the 2nd time (which make sense). Otherwise, it's always the one in memory executed the first time who is used.

 

Regards,

0 Kudos
Message 4 of 9
(4,556 Views)

You do not need to do the double release. Infact it is a bug to do the double release and will likely cause problems later if you do that. Instead you need to use the ReleaseSeqFile_UnloadFile option to ReleaseSequenceFileEx() when you are done with the file and only call it at the end, once per time you called GetSequenceFileEx. Please see the online help for the ReleaseSeqFileOptions constants for more information. Here's some of the text:

 

 

  • ReleaseSeqFile_UnloadFile–(Value: 0x4) Use this option to request TestStand to remove a sequence file from the engine's internal cache. When you specify this option, it does not guarantee that TestStand will remove the sequence file from the cache because there may be multiple references to it or it may be executing. If TestStand cannot remove a sequence file from the cache, the Engine.ReleaseSequenceFileEx method generates an error. Do not release the reference to a SequenceFile object until a call to the Engine.ReleaseSequenceFileEx method succeeds. If you do not specify this option, TestStand might remove the sequence file from the cache if TestStand no longer needs the file.


Also, the reason that release without this option does not unload the file is that the execution is still referencing it. But as long as the execution is done running then using the ReleaseSeqFile_UnloadFile option should work.

 

Hope this helps,

-Doug

0 Kudos
Message 5 of 9
(4,539 Views)

I tried with 0x04 and the only difference is the error is thrown when it can't unload the seq file (every time) instead of just ignoring the attempt.

 

In both case, when it gets to ReleaseSequenceFileEx(), the error is: Unable to unload sequence file 'xyz.seq' because it is in use, possibly because it is executing.

 

I only have one seq file and only one execution of it running in the GUI. I start it and terminate it. Make a change on the seq file and save it on disk and retry a start/terminate to verify if the new one is loaded (which is not because the 1st one is still in internal memory).

 

The code is pretty simple:

 

 //Get process model

                sequentialProcessModelSequenceFile = engineTS.GetSequenceFileEx("AlstomSequentialModel.seq", 0x6B,
                    TypeConflictHandlerTypes.ConflictHandler_Error);
 

 //Get client seq File

                clientSequenceFile = engineTS.GetSequenceFileEx(localSpecificSequenceFilePath, 0x03,
                            TypeConflictHandlerTypes.ConflictHandler_Error);

 

 //Launch execution with parameters

                axExecutionViewMgr.Execution = engineTS.NewExecution(clientSequenceFile, "Test UUT", sequentialProcessModelSequenceFile, false,
                        0x00, (object)parametersProcessModels, null, null);
 

//Wait for the end of it

                axExecutionViewMgr.Execution.WaitForEndEx(-1, true, null, null);

 

//release seq files
                engineTS.ReleaseSequenceFileEx(clientSequenceFile, 0x04); // I get the error here

 

                engineTS.ReleaseSequenceFileEx(sequentialProcessModelSequenceFile, 0x04);
 

I'm not sure what can be executing it since I'm waiting for the end of execution (the only one) before attempting to release it.

Could it be possible I need to do something with the ExecutionViewMgr?

I'm not sure also how I can get more informations to help me debug it. Is there flags or anything that could give me more hints where is the problem?

 

Thanks for your help, very appreciated!

Message Edited by MatLaroche on 03-01-2010 05:32 PM
0 Kudos
Message 6 of 9
(4,510 Views)

A few more ideas:

 

1) Are you perhaps using this file path with an ApplicationMgr or SequenceFileViewMgr API? You need to make sure that this file is not open by the ApplicationMgr or assigned to a sequencefileviewmgr as well. The applicationmgr or sequencefileviewmgr likely have a strong reference to the sequence file if you have assigned it or opened it with one of their APIs. You might want to try switching entirely to the applicationmgr APIs instead of using the engine APIs as that's probably less likely to lead to conflicts between the two.You could try ApplicationMgr.OpenSequenceFile() and ApplicationMgr.CloseSequenceFile().

 

2) Have you tried this with a simple, empty sequence file and simple default Sequential process model to verify that it's not related to anything in the sequence file you are running or any code elsewhere in your application? It's possible for code in the sequence or process model itself to be calling GetSequenceFile or GetSequenceFileEx.

 

3) Have you tried adding a delay between WaitForEndEx() and ReleaseSequenceFileEx()? This is not that likely to be the cause, but perhaps there is additional code required to execute in the execution thread after WaitForEndEx returns before the sequence file can be unloaded. If you add a small delay (i.e. Thread.Sleep(1000);) between those lines of code it might work. This would not explain why the file couldn't be reloaded when you use GetSequenceFileEx with the UpdateFromDisk flag though so probably is not the problem.

 

I tried to reproduce this problem in the sequence editor by running an execution with a sequence file, closing the sequence file, overwriting it with a different sequence file and reopening it and I was unable to reproduce the problem. I got the new file opened as expected. This is the equivalent situation since there is a completed execution still open. The sequence editor does not use the Unload flag on ReleaseSequenceFileEx, but it does use the UpdateFromDisk flag on GetSequenceFileEx() and it seems to work, correctly loading the new version of the file in this case. So there must still be something different in your case. I suspect that it's not the execution that has the extra reference in your case, but something else, perhaps the ApplicationMgr or SequenceFileViewmgr.

 

Also, as a side issue, if you are writing a custom UI, I'd recommend using UIMessages to determine when an execution completes rather than WaitForEndEx(). Basically handle the ApplicationMgr.UIMessageEvent and look for UIMsg_EndExecution and check that the execution associated with the UIMessage is the one you care about. Using the UIMessage like this has a couple of advantages:

1) It allows your UI to go back to executing in it's main message processing loop (Some things will not work correctly without this).

2) It gives you the potential to track and handle running multiple executions in parallel. Just look for and track the multiple UIMessages that such executions generate.

 

Please let us know if any of these ideas helps or if you are able to figure out the cause of the problem. If you are still unable to get it working and can't figure out the cause, please attach an example program and sequence files which reproduce the issue.

 

Hope this helps,

-Doug

Message Edited by dug9000 on 03-02-2010 10:03 AM
Message Edited by dug9000 on 03-02-2010 10:04 AM
Message 7 of 9
(4,495 Views)

Thanks for this very helpful post, I will try to look for those points. I tried quickly the delay after WaitEndEx without success. I also use a sequence containing only a pop-up now. I could try to use the default process model as well, but it needs some changes everywhere.

 

I know it doesn't make sense, but if I add the line in bold it all seems to work...!

The call with flag 0x00 fail to release (but don't generates an error) and the 2nd call with flag 0x04 is successful (since 0x04 generates an error if not).

 

//release seq files

                engineTS.ReleaseSequenceFileEx(clientSequenceFile, 0x00);
                engineTS.ReleaseSequenceFileEx(clientSequenceFile, 0x04); // I DONT get the error here anymore

 

                engineTS.ReleaseSequenceFileEx(sequentialProcessModelSequenceFile, 0x04);

 

This makes me believe I might have a count of 2 for the seq file in the internal cache. The first one decreases it to 1 and the last one makes it to 0 so the seq file unload (from my understanding). But I don't understand who has the 2nd count.

 

NI TestStand Help:

 

Engine.ReleaseSequenceFileEx()

Engine.ReleaseSequenceFileEx

This method removes a load reference from the sequence file. TestStand uses the load reference count to determine when to unload the sequence file from the engine's internal cache.

When you release the last load reference, TestStand unloads the file from the engine's internal cache. While unloading the file from the engine's internal cache, TestStand executes the SequenceFileUnload callback, if applicable.

If this method generates an error, TestStand does not release the object from the engine's internal cache. Only release the reference to a SequenceFile object if this method succeeds.

 

Your EndExecution suggestion made me think I also use the EndExecution event of the ExecutionViewMgr. I use it to get the state of the execution that ended.

                    e.exec.GetStates(out runState, out terminateState);

 

I removed this event just to make sure it wasn't causing the behavior and I had the exact same behavior so I don't think that's the problem.

 

I have a reporview, an execution view and a variable view, no seq file view in my GUI. I don't use any CommandKinds.

 

Is there a way to know the load reference count in the engine's internal cache? Or at least what else increase/decrease it?

 

0 Kudos
Message 8 of 9
(4,487 Views)

The fact that an extra release works indicates that somewhere else, either in the ApplicationMgr or perhaps in the process model or elsewhere, some other part of the code has an additional strong reference to the sequence file. It's better to find out where that is and fix that issue than to just add a double release at this other place in your code because otherwise, when the other code eventually tries to do the release that you have already done for it, it will get an error or other unexpected behavior.

 

If it's the applicationmgr that is getting this extra reference then using the applicationmgr to do the opening and closing of the sequence file instead of the engine might fix the problem. If it's the process model then using one of the default process models instead should make the problem go away.

 

-Doug

0 Kudos
Message 9 of 9
(4,482 Views)