Multiple Execution Constraints

I use execution constraints in my state machine architecture to make sure no state hangs up and stops the whole mess. They work really well mostly because (at least in my understanding) they run in a separate thread so almost no matter how badly I screw up a state, the execution constraint will fire and I can deal with the issue. Now I’d like to add a second execution constraint that runs simultaneously with the state execution constraint that makes sure the whole “mission” completes within a specified amount of time. Unfortunately, I don’t see a way to differentiate the 2 types of execution constraints and since I have to react differently to each type, I’m kind of stuck. The execution constraint shows a “message” property in the debugger that seems perfect for my needs but it isn’t documented in MSDN and I haven’t been able to figure out how to use it. Any suggestions will be greatly appreciated.

Thanks - Gene

PS Here’s a simple test program I’m using to see if I can make this work and a snapshot of what the debugger shows for the currentException.

using System;
using Microsoft.SPOT;

using System.Threading;

namespace missionExecutionConstraintTest
{
    public class Program
    {
        public static void Main()
        {
            bool missionRun = true;

            Debug.Print("ProgramStarted");

            ExecutionConstraint.Install(10000, 0); //10 second mission EC
            try
            {
                while (missionRun)
                {
                    try
                    {
                        ExecutionConstraint.Install(5000, 0); //5 second state EC
                        for (int i = 0; i < 1000; i++)
                        {
                            Debug.Print("i = " + i.ToString());
                            Thread.Sleep(500);
                        }
                    }
                    catch (Exception currentException)
                    {
                        if (currentException is ConstraintException)
                            Debug.Print("State Constraint Exception");
                    }
                }
            }
            catch(Exception currentException)
            {
                if (currentException is ConstraintException)
                    Debug.Print("Mission Constraint Exception");
            }
        }
    }
}

I always think of something obvious right after I push the Submit button. The situation is even worse than I thought. It looks like installing the state execution constraint replaces the mission execution constraint. Since my original test used 10 seconds for the mission EC and 5 seconds for the state EC, I didn’t see the problem. If is use 12 seconds for the mission EC and 5 seconds for the state EC, I never see an EC at 12 seconds. I’m still open for suggestions that might help me make this work.

@ Gene -
No expert but I believe it does not like the Thread.Sleep()

I looked at the underlying native code for ExecutionConstraint, which can be found here :[url] https://github.com/NETMF/netmf-interpreter/blob/a35ee529ce7930b31873d1524e9f44db1d4bbed3/CLR/Libraries/SPOT/spot_native_Microsoft_SPOT_ExecutionConstraint.cpp[/url]

It appears that you are right - there is only one sub-thread per main thread, so subsequent ExecutionConstraint.Install calls for the same owning thread will overwrite the previous ExecutionConstraint. That said, ExecutionConstraints are pretty simple and it should be straightforward to reproduce the functionality of ExecutionConstraint in a helper class that allows nesting. The native version just doesn’t support nested constraints from the same owning thread.

@ mcalsyn - Thanks for the confirmation. I took a look at the native code and am afraid working at that level is pretty far beyond my set of skills. I’ll go there if I have to but maybe I can find a solution using standard .Net Micro functionality. Right now I’m trying a solution where I start a new thread that does nothing but check the time and if the time is greater than my mission timeout, I’d like to throw an exception in the calling thread. Everything works fine except I haven’t been able to figure out how to throw an exception that can get caught in the calling thread. I’ve tried using ResetEvents but the only way I know how to do that requires the calling thread to be running the code that is waiting for the event. What I’m hoping to accomplish is have the mission timeout throw an exception that the main thread catches regardless of what it is doing even if it is doing something dumb like in an infinite loop or waiting for a character to arrive on a serial port or some other dumb mistake I might have made.