Main Site Documentation

Microsoft.SPOT.ConstraintException


#1

I’ve been writing some code that communicates to a server on a network and transfers data via TCP. The app will store data in flash memory if no network is available and send it later.

The app has several theads which deal with certain jobs include a thread to listen for instructions from the server and a thread to send information to the server. Understandably with different threads using the same resources I have had to use ‘lock’ statements to protect these resources when I can.

Now I am testing the code and I keep getting a Microsoft.SPOT.ConstraintException thrown occasionally more often than not when it is trying to acquire the lock. More worryingly, when this happens it seems to miss out the code I have in the finally section of a try…finally block.

I struggled to find any info on the web and so I decided to download the source code of the NetMF platform to try and find out exactly what was going on.

My investigations led me to this piece of code in Execution.cpp:


       //
        // Check constraints.
        //
        TINYCLR_FOREACH_NODE_BACKWARD(CLR_RT_SubThread,sth,th->m_subThreads)
        {
            if(sth->m_timeConstraint != TIMEOUT_INFINITE)
            {
                if(IsTimeExpired( s_compensation.Adjust( sth->m_timeConstraint ), timeoutMin, false ))
                {
                    (void)Library_corlib_native_System_Exception::CreateInstance( th->m_currentException, g_CLR_RT_WellKnownTypes.m_ConstraintException, S_OK, th->CurrentFrame() );

                    if((sth->m_status & CLR_RT_SubThread::STATUS_Triggered) == 0)
                    {
                        sth->m_status |= CLR_RT_SubThread::STATUS_Triggered;

                        //
                        // This is the first time, give it 500msec to clean before killing it.
                        //
                        sth->m_timeConstraint += TIME_CONVERSION__TO_MILLISECONDS * 500; CLR_RT_ExecutionEngine::InvalidateTimerCache();
                    }
                    else
                    {
                        CLR_RT_SubThread::DestroyInstance( th, sth, CLR_RT_SubThread::MODE_CheckLocks );

                        //
                        // So it doesn't fire again...
                        //
                        sth->m_timeConstraint = TIMEOUT_INFINITE;
                    }

                    th->Restart( true );
                }
            }
        }
        TINYCLR_FOREACH_NODE_END();

Now, I’m no expert on C++ or the NetMF framework but this code suggests to me that each thread is checked for a timeout. If it exceeds this timeout then it will raise the exception, and then, rather than honour any try…finaly or try…catch sections it simply restarts the thread!!!

If anyone can shed some light on this problem I would very much appreciate it. I can’t believe that I’m the only person who has experience this exception when locking.


#2

There are execution constraints in the MF, which are used to time an operation. But, your code has to call ExecutionConstrain.Install() to start and then uninstall.

Google Microsoft.SPOT.ConstraintException for further info.


#3

Hi Mike,

I think that’s the answer.

I am usingExecutionConstrain.Install() to force a timeout in a socket operation but I don’t have an uninstall call afterwards.

Thanks you.