NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

[SUPPORT REQUEST] [C# API] Using Execution.StepOver() to step through sequence; Execution.GetStates() always returning ExecRunState_Running

Hello everyone,

 

I am currently working on a project written in C#. I am executing the main sequence of a given sequence file. I want to execute it step by step and check/handle the result of every step immediately after its execution. My plan for this was to create a new execution with the "Break on first Step" option set to "true", and then execute one step at a time by using Execution.StepOver(). I ran into a few problems trying to get this to work, that's why I'm creating this topic. I think I spend about a day researching in the official documentation, google, and of course this forum. I couldn't find anything that would help me with this issue. 

When I execute the entire sequence at once without trying to break or step through it, everything works just fine. No issues here. However, when I try to create a suspended execution, I run into problems.

 

This is in essence the code I tried to use for this:

private void RunSequenceFile()
{
bool running = true;
execution = engine.NewExecution(sequenceFile, "MainSequence", null, /*break at first step*/true, 0);

while (running)
{
execution.StepOver();
running = WaitForStep();
/* handle result */
}
}

RunSequenceFile() is the method of a class that has the members "engine", "execution" and "sequenceFile". A new Execution is created and stored in "execution". For the new Execution, the parameter "breakAtFirstStep" is set to "true". The expected behaviour here is that the Execution will break before the first Step, and the ExecutionRunState should be "ExecRunState_Paused".

 

Next, a single Step is executed via Execution.StepOver(). Since the Execution is running in a separate thread, the Method WaitForStep() is used to wait for the Step Execution to be completed. The result of the Step will be handled after this.

My code for WaitForStep():

private bool WaitForStep()
{
	ExecutionRunStates execState = 0;
	do
	{
		execution.GetStates(out execState, out _);
		System.Threading.Thread.Sleep(100);
	} while (execState == ExecutionRunStates.ExecRunState_Running);

	return execState == ExecutionRunStates.ExecRunState_Paused;
}

The ExecutionRunState is being checked via Execution.GetStates(). During execution of the Step, the ExecutionRunState should be "ExecRunState_Running", and when the execution of the Step is finished, the ExecutionRunState should be "ExecRunState_Paused" again, or "ExecRunState_Stopped" when the main sequence is completed. So I'm waiting for the ExecutionRunState to be paused again. 

 

Here is where I am getting unexpected behaviour.

For some reason, the value returned by Execution.GetStates() is always "ExecRunState_Running". When I call GetStates() right after creating the Execution (breakAtFirstStep = true), the value is also "ExecRunState_Running".

Furthermore, StepOver() does not seem to do anything. I don't have any information about the state of my execution during runtime, so I tried calling StepOver() 5 times for a sequence with 4 Steps, with a 1000ms Sleep between creating the Execution and each StepOver(). The Execution should be completed after this. But "execution.WaitForEndEx(-1)" will still never return, and of course Execution.GetStates() will still return "ExecRunState_Running".

 

What I also tried.

This is not working for me:

execution = engine.NewExecution(seqFile, "MainSequence", null, true, 0);
System.Threading.Thread.Sleep(1000);
execution.Resume();
execution.WaitForEndEx(-1);

"Execution.Resume()" should resume the Execution and it should finish quickly with my example sequence files, but it won't.

 

I tried getting the reference to the current Step with "execution.GetThread(0).GetSequenceContext().Step", but this always gives me a null reference. I validated that there is only one Thread. I also tried this when testing Execution.StepOver() earlier.

 

I also tried creating the new Execution like this: "engine.NewExecution(seqFile, "MainSequence", null, false, 0x04);"

The parameter "breakAtFirstStep" is set to false here, but I'm passing "ExecutionTypeMask.ExecTypeMask_InitiallySuspended", which should, according to the documentation, give me the same expected behaviour as with setting "breakAtFirstStep = true". However, the behaviour I got was exactly the same I previously got, apart from Execution.Resume(), which would actually resume the execution.

 

I also tried setting both parameters, but got no different test results.

 

Can someone explain to me why I'm getting this behaviour? Am I having some major misconceptions about how this part of the API works?

I'm fairly new to TestStand and the API, so I'm happy about input on this topic.

 

 

kind regards

therealmaxmustermann

0 Kudos
Message 1 of 3
(2,882 Views)

There are several potential issues with what you are trying to do:

 

1) Are you doing this in the UI thread of the sequence editor or User-Interface? If so, you should not be because you will then be keeping UIMessages from being handled which will keep the execution from progressing. Windows messages need to be processed for UIMessages to be handled and that can't happen while you are executing code in the UI thread.

 

2) Break at first step means break at first user visible step. It does not mean that immediately after you call NewExecution that the execution will be in a paused state. For example, it will not break at all of the various steps that execution before mainsequence when you are using a process model.

 

3) InitiallySuspended does not mean the same thing as break at first step. It keeps the execution from executing anything at all until Resume is called. This is to allow modifying the execution or related datastructures before it starts to run.

 

4) There is a much easier way to add code around the execution of each step. You can create a SequenceFilePreStep, SequenceFilePostStep, StationPreStep, and/or StationPostStep callback sequence and put whatever code you want to execution before or after each step there. If you control the UI itself and are customizing the UI you could also use the Execution.AddPostStepCustomUIMessage() feature instead which will give you better performance than the callbacks and allow you to handle things directly in the UI code rather than in sequences.

 

Hope this helps,

-Doug

0 Kudos
Message 3 of 3
(2,821 Views)