Unexplained thread exits

My program is ending without error for, as far as I can tell, no reason. My clock watcher thread starts up ok, then it just quits. One time I got the message that it received no debugging information, but my clock display kept going, but most of the time it just exits with code 0 and no information at all.

Does anyone see anything totally obviously wrong with these two bits?

Relevant/end portion of the main loop:


           // create clock thread
            Thread ClockThread = new Thread(new ThreadStart(ClockWatcher));
            // bind handler for when seconds changes
            SecondElapsed += new SecondElapsedHandler(SecondElapsedEvent);
            // start the thread
            ClockThread.Start();

            // run until the end of time
            Thread.Sleep(Timeout.Infinite);

Clock thread:


        /// <summary>
        /// Clock watcher thread, runs forever
        /// </summary>
        public static void ClockWatcher()
        {
            // sleep time compensation, how long does it take to wake up?
            const int sleepComp = 15;
            TimeEventArgs e = new TimeEventArgs(DateTime.MinValue);
            int originalSec = -1;
            int secondIn, sleeptime;
            while (true)
            {
                // get current time
                e.event_time = DateTime.Now;
                if (e.event_time.Second != originalSec)
                {
                    // use the current time as a reference for next check
                    originalSec = e.event_time.Second;

                    // fire second event
                    SecondElapsed(null, e);
                    // fire minute event
                    if (e.event_time.Second == 0) MinuteElapsed(null, e);
                    // fire hour event
                    if (e.event_time.Minute == 0) HourElapsed(null, e);
                    // fire day event
                    if (e.event_time.Hour == 0) DayElapsed(null, e);
                }
                // there will be a new second in X ms
                secondIn = (1000 - e.event_time.Millisecond);
                // subtract the sleep compensation to find how long to sleep
                sleeptime = secondIn - sleepComp;
                //Debug.Print("Sleep time: " + sleeptime.ToString());
                // if it's worth sleeping, sleep
                if (sleeptime > sleepComp) Thread.Sleep(sleeptime);
                // loop again                    
            }
        }

If I bind an event handler in a thread that is asleep when the event is later fired? Do the events all happen in a separate, implicit thread?

Do I need to bind my events in an event processing thread?

Are you sure your thread has stopped? Have you verified that it has stopped in the debugger? Have you single stepped in the debugger to verify that the thread is operating as expected?

during single step, the debugger disconnects and the project shows as no longer debugging. However as I mentioned in the one instance my clock kept updating the display (in a handler listening for the SecondElapsed event).

I didn’t post the complete code as I figured no one would want to sift through all of that. The other reason was because as far as I can tell the problem lies in these two bits as they were the only two I changed before it quit working.

Forget the code for a minute- can you tell me if bound event listeners are automatically fired in their own thread or what thread the execute in when the event fires?

Eg if my main function/thread is sleeping, and an event is bound during the main thread/function, does it wake the thread, does it start a new thread? Eg should i create a separate thread to do the event binding in so the event fired subs happen in that thread?

the thread that is processing an event depends upon whether you are using gadgeteer or regular sdk.

normally, event callbacks are processed in the thread that fired the event.

gadgeteer uses a different mechanism. events are processed in an event thread.

@ Mike, I am new to these devices, so this is not to argue, but to ensure that I have understood the concepts correctly.

My understanding is as follows. Event handers always run on the thread that they are invoked from unless they have been explicitly marshaled to another thread. Now I see in the Gadgeteer device drivers the extra step is taken to marshal the invocation of the event handler to the dispatcher thread. However, unless this extra work is done the event handlers will run on the firing thread.

I mention this, because I notice that @ btrotter is firing an event from within the ClockWatcher thread


// fire second event
SecondElapsed(null, e);

Given this code which invokes the event delegate directly, the attached handlers will run on the ClockWatcher thread. Depending on what those handlers are doing there is a potential race condition. I think we need to see this code.

Thanks for all the insight.

This is all on a FEZ Cobra. Is there a / what is the way to marshal the listeners for the *Elapsed events to new threads?

By the way, at the moment, the only event being listened for is the SecondElapsed one.

If you guys really want to take the time to see the whole code, I just posted it on code share as is. http://www.tinyclr.com/codeshare/entry/431

Thanks for all the help! If you have any suggestions how to better implement or tune my clock watcher loop, I’d love any input. I hope to make this a long term project that is continually improving.

Is there any chance that the Minute/Hour/DayElapsed events don’t have anybody registered to receive them?

Yes, I’m only using the seconds one at the moment. I wish the debugger would print more information if that’s why its dying. I’ll give it a try. It’s been a while since I was into C# (nearly a decade!) and Events are a bit fuzzy for me :slight_smile:

Edit: I made the changes, and it seems to work now. Thanks for catching that bonehead mistake! That’s probably why it was hanging some of the time and not others.

I’m also still interested in learning how to make the event listener functions run in their own thread(s).

There ya go…

Event members are null if nobody’s registered to them. To avoid this sorta thing, do something like “if (MyEvent != null) MyEvent (yadda, yadda);”

I haven’t run into it on .NETMF but I’ve been tortured in the past with full .NET programs just stopping if you take an exception when being called from Windows itself - async callbacks are usually what bite me. I guess timers/events might have the same issue…

In the future, a try/catch block around code you really care about is sometimes useful. Maybe get out a debug message before it all explodes.

[quote=“loconut”]I’m also still interested in learning how to make the event listener functions run in their own thread(s).
[/quote]
On full .NET, instead of using C# events, I’d probably start a thread then have it wait on an AutoResetEvent. The main thread can kick that when it wants the thread to wake up.

There may well be better/faster/cheaper ways to do this in .NETMF.

Thanks for all the help/feedback. It’s nice to be making progress even if it was a dumb mistake that tripped me up.

Any word on how to marshal event handlers into a particular thread?

to see how to marshal events to a specific thread look at the core source code for the Gadgeteer library.

Why do you need to do this?

The idea was to have all things that start happening as a result of time events to happen in their own thread (or threads) so that they don’t prevent the clock or anything else from doing their business.

timer events happen in the user interrupt handler thread. this is MF thread, not a user started thread.