Main Site Documentation

Calling event handlers from module doesn't work when using Gadgeteer.Timer


#1

I change source code for TemperatureHumidity module to work with Pins (I have Cerb40). The only change in code is constructor.
I experienced some really strange problem in calling event:

 protected virtual void RaiseMeasurementCompleteEvent(object sender, double temperature, double relativeHumidity)
        {
            if (_OnMeasurementComplete == null) 
                _OnMeasurementComplete = new MeasurementCompleteEventHandler(RaiseMeasurementCompleteEvent);
            if (Program.CheckAndInvoke(MeasurementComplete, _OnMeasurementComplete, sender, temperature, relativeHumidity))  //PROBLEM LINE
            {
                MeasurementComplete(sender, temperature, relativeHumidity);
            }
        }

CheckAndInvoke returns true and the event is called. But when I use Gadgeteer.Timer in Main method of Cerb40, the CheckAndInvoke returns false. Only when creating an object. It doesn’t have anything with adding Gadgeteer library to References.

        public static void Main()
        {
            module = new TemperatureHumidityIO(Pin.PC0, Pin.PC1);            
            Gadgeteer.Timer timer;
            timer = new Gadgeteer.Timer(new TimeSpan(0, 10, 0));     //WHEN NOT IN COMMENT, THE CheckAndInvoke RETURNS FALSE.
            Thread.Sleep(Timeout.Infinite);
        }

Can someone explain to me this behaviour please.
Do I have to change the event caller method, or not using Gadgeteer.Timer (only System.Threading.Timer)?


#2

Is this a Gadgeeter project? If so, you should not be including any initialization code in the Main method. That is what ProgramStarted is for…

If it is not a Gadgeteer project, then why are you using a Gadgeteer timer?

I am confused…


#3

Dispatcher runs on the same thread as your program code.
Any method which contains an infinite loop will prevent the dispatcher from notifying your
program about events.


#4

It is not Gadgeteer (Cerb40). I am using Gadgeteer.Timer because it’s nicer. ;D And I didn’t have any problems until now. (I am using the same code in Cobra II) :slight_smile:
So using System.Threading.Timer is a way to go?


#5

CheckAndInvoke is also a Gadgeteer method. I would expect that using Gadgeteer stuff in a non-Gadgeeter project would cause all sorts of funny things to happen… or not happen…

As far as not having problems until now… I would have to review the Gadgeeter code to answer that question. But that would not be productive.

I would use the Thread timer.


#6

as tvinko said.
NETMF uses only one thread for all timers, and probably also the same thread for events.
So any timer / event must return before the next one can execute.
You have to make sure that the code in the event / timer callbacks is really short.
You could start a thread or signal a waiting thread to start in callback for example.
For some situations my thread pool comes in handy:
https://www.ghielectronics.com/community/codeshare/entry/806