Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

how to end a NativeEventHandler Thread


  • Please log in to reply
10 replies to this topic

#1 henryyao

henryyao

    Member

  • Members
  • PipPip
  • 19 posts

Posted 20 December 2012 - 09:58 PM

I'm having a problem with ending a NativeEventHandler(button). The problem is main thread stuck at the join() function. I dont understand why the childthread is not released after it is run.

public class Program
    {
        private static Thread mainThread;
        private static Thread childThread;     

        private static InterruptPort button = new InterruptPort(Pins.GPIO_PIN_D1, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLevelHigh);
      
        private static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
        
        public static void Main()
        {            
            mainThread = Thread.CurrentThread;
            Thread.Sleep(1000);
            while (true)
            {
                Thread.Sleep(100);
                button.OnInterrupt += new NativeEventHandler(ButtonEvent);
                mainThread.Suspend();
                childThread.Join();//It stuck here.
                Thread.Sleep(100);
                button.EnableInterrupt();
                button.ClearInterrupt();  
            }
        }

        private static void ButtonEvent(uint port, uint state, DateTime time)
        {
            childThread = Thread.CurrentThread;
            button.DisableInterrupt();          
            mainThread.Resume();
           // Thread.CurrentThread.Abort(); this .Abort() seems doesn't terminate the thread either.
        }
    }


#2 Thomas Rankin

Thomas Rankin

    Member

  • Members
  • PipPip
  • 26 posts

Posted 21 December 2012 - 02:04 AM

Have you looked at the advanced tutorials example on
http://www.netduino.com/projects/

I think it is a working example of your objective. I apologize for not answering why your code doesn't work.


I'm having a problem with ending a NativeEventHandler(button). The problem is main thread stuck at the join() function. I dont understand why the childthread is not released after it is run.

public class Program
    {
        private static Thread mainThread;
        private static Thread childThread;     

        private static InterruptPort button = new InterruptPort(Pins.GPIO_PIN_D1, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLevelHigh);
      
        private static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
        
        public static void Main()
        {            
            mainThread = Thread.CurrentThread;
            Thread.Sleep(1000);
            while (true)
            {
                Thread.Sleep(100);
                button.OnInterrupt += new NativeEventHandler(ButtonEvent);
                mainThread.Suspend();
                childThread.Join();//It stuck here.
                Thread.Sleep(100);
                button.EnableInterrupt();
                button.ClearInterrupt();  
            }
        }

        private static void ButtonEvent(uint port, uint state, DateTime time)
        {
            childThread = Thread.CurrentThread;
            button.DisableInterrupt();          
            mainThread.Resume();
           // Thread.CurrentThread.Abort(); this .Abort() seems doesn't terminate the thread either.
        }
    }



#3 henryyao

henryyao

    Member

  • Members
  • PipPip
  • 19 posts

Posted 21 December 2012 - 05:02 AM

Have you looked at the advanced tutorials example on
http://www.netduino.com/projects/

I think it is a working example of your objective. I apologize for not answering why your code doesn't work.


I have looked at the tutorial.

I have posted the same quesiton on stackoverflow and someone answered it. And now i think the problem is that I should not be adding the event handler over and over in the loop.

And for other people new to C#, I would recommend AutoResetEvent instead of resume/suspend. The AutoResetEvent is introduced in the 4th example in the following tutorial.
http://forums.netdui...tronic-project/

#4 mackelen

mackelen

    Member

  • Members
  • PipPip
  • 10 posts
  • LocationVeghel - Netherlands

Posted 22 December 2012 - 11:22 AM

Hi Henry, There are quite some things wrong in your program. First of all, what are you trying to accomplish ? Do you want to receive a trigger when a button is pressed ? 1) In your program you are suspending/resuming/joining the main thread, even in the while loop which is running on that particular thread. 2) The subscription on the OnInterrupt event should be made before entering the while loop, the same goes with 'button.EnableInterrupt'. 3) There is no need for suspend/resume/join in this program, how did you come up with this ? 4) Why are you calling 'button.DisableInterrupt' in the event handler ? 5) Are you trying to quit the main while loop when a button is pressed ? If so use either a ManualResetEvent or an AutoResetEvent at which the while loop keeps running till it is signaled. (Use WaitOne with a timeout).

#5 henryyao

henryyao

    Member

  • Members
  • PipPip
  • 19 posts

Posted 22 December 2012 - 04:17 PM

Hi Henry,

There are quite some things wrong in your program. First of all, what are you trying to accomplish ? Do you want to receive a trigger when a button is pressed ?

1) In your program you are suspending/resuming/joining the main thread, even in the while loop which is running on that particular thread.
2) The subscription on the OnInterrupt event should be made before entering the while loop, the same goes with 'button.EnableInterrupt'.
3) There is no need for suspend/resume/join in this program, how did you come up with this ?
4) Why are you calling 'button.DisableInterrupt' in the event handler ?
5) Are you trying to quit the main while loop when a button is pressed ? If so use either a ManualResetEvent or an AutoResetEvent at which the while loop keeps running till it is signaled. (Use WaitOne with a timeout).


1)I thought the ButtonEvent is a new thread.I think that's what they meant in the third example(P.27) in tutorial http://forums.netdui...attach_id=1168. But I now get that the childthread and the mainthread are the same thing.
2)you are absolute right about that.
3)again from that tutorial.
4)Because I dont want to trigger the handler again when the ButtonEvent function is running(its infact not a button, its a motion detector, so I dont want to multi-trig the Button Eventin a very short time). I guess the triggering event may be accumulated, waiting in a queue to be handled, it's like scanf() in C.
5)It's a loop for forever detection if the motion detector is triggered or not.

Please corret me if I was wrong,thanks.

#6 mackelen

mackelen

    Member

  • Members
  • PipPip
  • 10 posts
  • LocationVeghel - Netherlands

Posted 23 December 2012 - 07:55 AM

4)Because I dont want to trigger the handler again when the ButtonEvent function is running(its infact not a button, its a motion detector, so I dont want to multi-trig the Button Eventin a very short time). I guess the triggering event may be accumulated, waiting in a queue to be handled, it's like scanf() in C.
5)It's a loop for forever detection if the motion detector is triggered or not.

Please corret me if I was wrong,thanks.


The nice things about PIRs is that they have an internal mechanism which will ensure that they will not overload the user of their output. So in most cases this will only change every few seconds when there is a lot of movement. So no need to stop the interrupt. One word of caution, be aware that the activity done in the event handler should not take too much time. So for starters you could add a Debug.Print in the event handler which shows you that movement has detected. There should not be any more code that the Debug.Print.

The main while should be just that for now, an empty while: "while (true);".

#7 henryyao

henryyao

    Member

  • Members
  • PipPip
  • 19 posts

Posted 23 December 2012 - 04:12 PM

The nice things about PIRs is that they have an internal mechanism which will ensure that they will not overload the user of their output. So in most cases this will only change every few seconds when there is a lot of movement. So no need to stop the interrupt. One word of caution, be aware that the activity done in the event handler should not take too much time. So for starters you could add a Debug.Print in the event handler which shows you that movement has detected. There should not be any more code that the Debug.Print.

The main while should be just that for now, an empty while: "while (true);".


Thanks mackelen. Could you explain more about why "be aware that the activity done in the event handler should not take too much time.", I'm putting lots of functions in my new event handler, so I'd like to know if this will cause some trouble.

#8 mackelen

mackelen

    Member

  • Members
  • PipPip
  • 10 posts
  • LocationVeghel - Netherlands

Posted 24 December 2012 - 09:48 AM

Thanks mackelen. Could you explain more about why "be aware that the activity done in the event handler should not take too much time.", I'm putting lots of functions in my new event handler, so I'd like to know if this will cause some trouble.


In my specific case I had problems when doing some processing in the handling of the action and when the interrupt would occur multiple times. I fixed this by passing the execution (via a queue I built) onto a separate thread.

However in your specific case this will probably not be a big issue since the interrupt is only fired when movement is detected. But the best way to find out is just to try it :)

#9 NooM

NooM

    Advanced Member

  • Members
  • PipPipPip
  • 490 posts
  • LocationAustria

Posted 24 December 2012 - 10:00 AM

interrupt would occur multiple times. I fixed this by passing the execution (via a queue I built) onto a separate thread.


thats bad, when that happens often your queue will eat up all your memory and it will throw an out of mem exception.



the best way of doing all your stuff is just read the raw data in yor handler, and than process it in a thread your your main loop.

#10 mackelen

mackelen

    Member

  • Members
  • PipPip
  • 10 posts
  • LocationVeghel - Netherlands

Posted 24 December 2012 - 03:03 PM

thats bad, when that happens often your queue will eat up all your memory and it will throw an out of mem exception.



the best way of doing all your stuff is just read the raw data in yor handler, and than process it in a thread your your main loop.


That's exactly what the queue does ...

#11 Arron Chapman

Arron Chapman

    Advanced Member

  • Members
  • PipPipPip
  • 289 posts
  • LocationOregon, USA

Posted 24 December 2012 - 05:32 PM

The main while should be just that for now, an empty while: "while (true);".


while(true); will cause the uC to run code infinitely specifically a jump instruction and a nop if I'm not mistaken. It's often better to use Thread.Sleep(Timeout.Infinite); which causes the thread to sleep. In the case of a while(true) if you are processing in other threads, the thread running the loop still needs processor time, however a thread that is sleeping does not.

When you talk EE use small words, I'm just a Software Developer :)
My Blog/Site and Everything Else

If my post helped you please consider pressing the "Like This" button in the bottom right-hand corner.

 

Oh my. So many things, so little money!!

 





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.