3

I'm using a Netduino board and 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.
    }
}
henryyao
  • 1,758
  • 6
  • 23
  • 37
  • I would think the join is unnecessary. The child thread is resuming the main thread and then exiting. The child thread should be done anyway. What is the state of the child thread (see the debug Threads window) at the join? – Pete Dec 20 '12 at 22:10
  • Incidentally: http://msdn.microsoft.com/en-us/library/system.threading.thread.suspend.aspx See the caution in the remarks section. This is not really a good way to perform synchronization. Furthermore, you're subscribing to the OnInterrupt event in every iteration of the loop. That's going to cause problems. – Pete Dec 20 '12 at 22:14
  • Incidentally, why all the thread stuff in the first place? – Pete Dec 20 '12 at 22:20
  • @Pete Thanks for the reply. I'm now using AutoResetEvent instead of suspend() and resume(). Another thing I should not subscribe to the OnInterrupt in every iteration of loop, but I thought that the new NativeEventHandler(ButtonEvent) object should be released from the memory everytime it is done, so there will be only one instance at anytime, isn't it ? – henryyao Dec 20 '12 at 22:53
  • @Pete I really dont know Object oriented, I was a C programmer. That's why when it comes to OO ,i got LOST. So what do you mean by " thread stuff in the first place"? how can I change that? – henryyao Dec 20 '12 at 22:58
  • I don't get this. Don't `mainThread` and `childThread` point to the same thread? Also, you seem to be adding the event handler over and over in the loop. Not a good idea. – Brian Rasmussen Dec 20 '12 at 23:44
  • @BrianRasmussen If i'm not wrong, the mainThread and childThread do not point to the same thread. Here is what i thought: When I pushed the button, it will trigger a new thread “ButtonEvent()”. So now there will be two different threads in this process, which are the mainThread and childThread. – henryyao Dec 21 '12 at 04:59

1 Answers1

4

First of all, when you subscribe to an event, you stay subscribed until you unsubscribe. So you only need to subscribe once.

I believe you can do the netduino like this...

public class Program
{
    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()
    {            
        button.OnInterrupt += new NativeEventHandler(ButtonEvent);
        Thread.Sleep(Timeout.Infinite);
    }

    private static void ButtonEvent(uint port, uint state, DateTime time)
    {
        ... do whatever here ...
    }
}

So basically, whatever you want to happen when the button is pressed, do in the ButtonEvent

I don't think you need to do anything else beyond that.

The:

Thread.Sleep(Timeout.Infinite);

simply serves to keep the program running.

So in the ... do whatever here ... you could flash your LED or whatever you want to do.

Pete
  • 6,585
  • 5
  • 43
  • 69