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. } }
how to end a NativeEventHandler Thread
#1
Posted 20 December 2012 - 09:58 PM
#2
Posted 21 December 2012 - 02:04 AM
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
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
Posted 22 December 2012 - 11:22 AM
#5
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
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
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
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
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
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
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