ThreadState Bug on G120HDR, NETMF 4.2QFE2

Hi,

I have a strange bug that moreover is a problem when trying to manage threads status correctly.

My ThreadState is set to Suspended, that is what I effectively want to have, but when managing a switch/case on the several states, the revelant cas if shown to be “Running” instead of what is shown in the tooltip !!!

Does anybody ever seen such a situation ?

See attachment for more details

Have you tested this on emulator?

May be because it was running before hitting your breakpoint.:wink:

@ Gus -

Yes, and it gives something different : WaitSleepJoin | Suspended instead of Suspended…So also uncasable…

I give you my test code so that you would check if something is comming wrong…


using System;
using Microsoft.SPOT;
using System.Text;
using System.Threading;
using System.IO;

namespace MFConsoleApplication1
{

    public class ThreadTester
    {
        private Thread m_serverThread = null;
        private static bool m_ShouldStop = false;

        private void RunServer()
        {
            while (!m_ShouldStop)
            {
                Debug.Print("------------------------------Lopping...");
                System.Threading.Thread.Sleep(500);
            }
        }

        public ThreadTester()
        {
            m_serverThread = new Thread(new ThreadStart(RunServer));
        }

        public void Start()
        {
            try
            {
                m_ShouldStop = false;

                m_serverThread = new Thread(new ThreadStart(RunServer));
                switch (m_serverThread.ThreadState)
                {
                    case ThreadState.Stopped :
                        m_serverThread.Start();
                        while (!m_serverThread.IsAlive) Thread.Sleep(10);
                        break;
                    case ThreadState.Unstarted:
                        m_serverThread.Start();
                        while (!m_serverThread.IsAlive) Thread.Sleep(10);
                        break;
                    case ThreadState.Suspended:
                        m_serverThread.Resume();
                        while (!m_serverThread.IsAlive) Thread.Sleep(10);
                        break;
                }
            }
            catch
            {
                if (m_serverThread != null) Stop();
            }
        }

        public void Stop()
        {
            m_ShouldStop = true;
            while (m_serverThread.IsAlive) Thread.Sleep(100);
        }

        public void Suspend()
        {
            m_serverThread.Suspend();
        }

        public string GetStatus()
        {
            switch (m_serverThread.ThreadState)
            {
                case ThreadState.Stopped:
                    return "Stopped";
                case ThreadState.Unstarted:
                    return "Unstarted";
                case ThreadState.Suspended:
                    return "Suspended";
                case ThreadState.WaitSleepJoin:
                    return "WaitSleepJoin";
                case ThreadState.Running:
                    return "Running";
            }
            return "Unknown";
        }
    }

    public class Program
    {
        public static void Main()
        {
            ThreadTester _tester = new ThreadTester();

            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);

            _tester.Start();
            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);
            //
            _tester.Suspend();
            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);
            //
            _tester.Start();
            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);
            //
            _tester.Stop();
            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);
            //
            _tester.Start();
            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);
            //
            _tester.Stop();
            Debug.Print(_tester.GetStatus());
            Thread.Sleep(2000);

            Thread.Sleep(Timeout.Infinite);
        }

    }
}

Even if I make a loop until !IsAlive, it does not change anything…

Added some couple of states :


            switch (m_serverThread.ThreadState)
            {
                case ThreadState.Stopped:
                    return "Stopped";
                case ThreadState.Unstarted:
                    return "Unstarted";
                case ThreadState.Suspended:
                    return "Suspended";
                case ThreadState.WaitSleepJoin:
                    return "WaitSleepJoin";
                case ThreadState.Running:
                    return "Running";
            }
            return "Unknown";

But really sound like if there was a mapping problem between the enum and the states in code…Or even ThreadState if not safe anymore !

Full sample code corrected with IsAlive and Thread.Sleep at the end of Main, but do not change many things…

And also the same code on G120HDR give the same results…

OK, reason found !!!

When you use a ThreadSleep into a thread, or any other locking type instruction, WiatSleepJoin is also invoked !

So if you want to make some sleep in a thread, and also manage its state, you have to find another way to do…

Look at this for more explanations :