C# K8090 - Do not get the K8090Board.CommandReceived message

I have made a wrapper for the K8090Board class and I can connect and turn on/off the relays but I do not get the CommandReceived-message back when querying the relays status.
I am working with Windows 8.1 64 Bit and C#. Does anyone have a hint of what the problem could be?

using System;
using Velleman.Kits;

namespace REL
{

    public class Relay
    {

        // Variables
        private K8090Board _k8090Board;
        private int[] _relayStatuses = {0,0,0,0,0,0,0,0};
        private Boolean _jumperSet;
        private String _firmwareVersion = "";
        private readonly byte[] _relayMasks = {128, 64, 32, 16, 8, 5, 4, 2, 1};
       
        // Constructor
        public Relay(String port)
        {
            // Connect to K89090
            _k8090Board = new K8090Board(port);
            _k8090Board.Connect();
            System.Threading.Thread.Sleep(1000);

            // Register call-back
            _k8090Board.CommandReceived += K8090Message;

            // Ask for status and meta-data
            QueryRelayStatus();
            QueryFirmwareVersion();
            QueryRelayStatus();

        }

        // Query board statuses
        private void QueryRelayStatus()
        {
            _k8090Board.SendCommand(K8090Command.QueryRelayStatus);
        }
        private void QueryFirmwareVersion()
        {
            _k8090Board.SendCommand(K8090Command.FirmwareVersion);
        }
        private void QueryJumperStatus()
        {
            _k8090Board.SendCommand(K8090Command.GetJumperStatus);
        }
        private void K8090Message(object sender, Velleman.Kits.CommandEventArgs e)
        {

            // Process relay status message
            if (e.cmd == Velleman.Kits.K8090Command.RelayStatus)
            {
                for (int i = 0; i < 7; i++)
                  _relayStatuses[i] = e.param1 & _relayMasks[i];
            }
            
            // Process firmware message
            if (e.cmd == Velleman.Kits.K8090Command.FirmwareVersion)
            {
                _firmwareVersion = e.param1 + "-" + e.param2;
            }

            // Process jumper status
            if (e.cmd == Velleman.Kits.K8090Command.FirmwareVersion)
            {
                _jumperSet = (e.param1 > 0x01);
            }


        }

        // Set commands
        public void SetRelayOn(int relay)
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOn, _relayMasks[relay]);
        }
        public void SetRelayOff(int relay)
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOff, _relayMasks[relay]);
        }
        public void SetAllRelaysOn()
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOn, (byte)0xff);
        }
        public void SetAllRelaysOff()
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOff, (byte)0xff );
        }

        // Get calls
        public Boolean GetRelayStatus(int relay)
        {
            return _relayStatuses[relay]==1;
        }
        public int[] GetRelayStatuses()
        {
            return _relayStatuses;
        }
        public Boolean GetJumperSet()
        {
           return _jumperSet;    
        }

        public String GetFirmwareVersion()
        {
            return _firmwareVersion;
        }

        // System calls
        public void SetFactoryDefault()
        {
            _k8090Board.SendCommand(K8090Command.ResetFactoryDefaults);            
        }


    }
}

To understand why, you first need to forget the concept of sequential code. Take for example a simple button on a windowed application. When you click on the button with your mouse, the code attached to that button will run. This is the same for the K8090, whenever the K8090 sends a packet to the computer, the CommandReceived event will run. This means that your wrapper object must still be listening for packets, just as your button is listening for mouse clicks.

To be able to achieve this, you will need a Windows Forms application, and you will need to make sure that your wrapper object exists for the entire duration of the application, so it can listen for packets. Console applications are not ok because they are sequential, they can’t handle the concept of packets arriving willy nilly. Actually, they can, but not with the technique used in this library.

The K8090 installer comes with a working example in VB.NET.

Thanks for the answer but I found the problem though. The DLL was in an unstable state for some reason. A reboot fixed the problem.
Now it is working like a dream. I publish my code again after testing and removal of bugs, if somebody wants to use it. All functions of the K8090 are not implemented, only the the ones I needed for the project.


using System;
using Velleman.Kits;


namespace REL
{

    public class Relay
    {

        // Variables
        private K8090Board _k8090Board;
        private int[] _relayStatuses = {0,0,0,0,0,0,0,0};
        private Boolean _jumperSet;
        private String _firmwareVersion = "";
        private readonly byte[] _relayMasks = {1,2,4,8,16,32,64,128};
       
        // Constructor
        public Relay(String port)
        {
            // Connect to K89090
            _k8090Board = new K8090Board(port);
            _k8090Board.Connect();
            System.Threading.Thread.Sleep(1000);

            // Register call-back
            _k8090Board.CommandReceived += K8090Message;

            // Ask for status and meta-data
            QueryRelayStatus();
            QueryFirmwareVersion();
            QueryRelayStatus();

        }

        // Query board statuses
        private void QueryRelayStatus()
        {
            _k8090Board.SendCommand(K8090Command.QueryRelayStatus);
        }
        private void QueryFirmwareVersion()
        {
            _k8090Board.SendCommand(K8090Command.FirmwareVersion);
        }
        private void QueryJumperStatus()
        {
            _k8090Board.SendCommand(K8090Command.GetJumperStatus);
        }
        public void K8090Message(object sender, Velleman.Kits.CommandEventArgs e)
        {

            // Process relay status message
            if (e.cmd == Velleman.Kits.K8090Command.RelayStatus)
            {
                for (int i = 0; i < 8; i++)
                  _relayStatuses[i] = e.param1 & _relayMasks[i];
            }
            
            // Process firmware message
            if (e.cmd == Velleman.Kits.K8090Command.FirmwareVersion)
            {
                _firmwareVersion = e.param1 + "-" + e.param2;
            }

            // Process jumper status
            if (e.cmd == Velleman.Kits.K8090Command.GetJumperStatus)
            {
                _jumperSet = (e.param1 > 0x01);
            }


        }

        // Set commands
        public void SetRelayOn(int relay)
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOn, _relayMasks[relay]);
        }
        public void SetRelayOff(int relay)
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOff, _relayMasks[relay]);
        }
        public void SetAllRelaysOn()
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOn, (byte)0xff);
        }
        public void SetAllRelaysOff()
        {
            _k8090Board.SendCommand(K8090Command.SwitchRelayOff, (byte)0xff );
        }

        // Get calls
        public Boolean GetRelayStatus(int relay)
        {
            return _relayStatuses[relay]==1;
        }
        public int[] GetRelayStatuses()
        {
            return _relayStatuses;
        }
        public Boolean GetJumperSet()
        {
           return _jumperSet;    
        }

        public String GetFirmwareVersion()
        {
            return "v" +_firmwareVersion;
        }

        // System calls
        public void SetFactoryDefault()
        {
            _k8090Board.SendCommand(K8090Command.ResetFactoryDefaults);            
        }


    }
}