在事件被触发之前不会继续的方法

时间:2016-06-28 14:26:19

标签: c# multithreading event-handling serial-port

我有一个通过COM-Port链接到多个传感器的GUI。我有一个Datahandler,可以确保收到和发送的包具有正确的大小和内容。然后我有一个包含所有传感器的SensorContainer,每当添加新传感器时都会触发事件!

我现在的问题是: 我需要一种方法,只需点击一下即可初始化所有传感器。

我不能这样做。如果我逐个初始化它们,它可以工作,但所有方法都不起作用。 我的想法是包被混合,处理程序不再接受传感器进行初始化。所以我试图让方法等待第一个传感器初始化和继续,但我不知道如何! 我用多线程尝试了一些东西,但是我并没有在那个领域真正经历过,而且最终它还没有成功......

SensorContainerClass

public static class SensorContainer
    {
        public static event EventHandler<ContainerEvent> ContainerChanged;

        public static ObservableCollection<Sensor> SensorList
        {
            get { return _sensorList; }
        }


        public static void AddSensor(Sensor sensor)
        {
            Sensor sensorExists = GetSensor(sensor.Address);
            if (sensorExists == null)
            {

                Application.Current.Dispatcher.Invoke(() => _sensorList.Add(sensor));
                ContainerChanged(null,new ContainerEvent(sensor.Address, true));

            }
            else
            {
                Console.WriteLine("It's not possible to add multiple sensors with the same address.");
            }
        }
        public static void RemoveSensor(Sensor sensor)
        {
            Sensor sensorExists = GetSensor(sensor.Address);
            if (sensorExists != null)
            {
                Application.Current.Dispatcher.Invoke(() => _sensorList.Remove(sensor));
                ContainerChanged(null, new ContainerEvent(sensor.Address, false));
            }
            else
            {
                Console.WriteLine("No sensor with address " + sensor.Address);
            }
        }

        public static Sensor GetSensor(byte address)
        {
            foreach (Sensor sensor in _sensorList)
            {
                if (sensor.Address == address)
                {
                    return sensor;
                }
            }
            return null;
        }

        // members
        private static readonly ObservableCollection<Sensor> _sensorList = new ObservableCollection<Sensor>();

    }

的DataHandler

public class DataHandler:ModelBase
    {
        private const int MAX_TIMER_TIME = 500;
        public long answertime_milli;
        Timer aTimer;
        Stopwatch watch;


        Sensor tempSensor;

        private byte[] tempFrame;
        private bool framePartPendingFlag = false;
        public bool framesEqual;
        public bool initalisationFlag = false;
        public InitType initialisationType;


        public byte[] TxFrame
        {
            get { return txFrame; }
        }

        public byte TxAddress
        {
            get { return TxFrame[0]; }
        }

        public byte TxLength
        {
            get { return TxFrame[1]; }
        }

        public byte TxCommand
        {
            get { return TxFrame[2]; }
        }

        public byte[] TxData
        {
            get { return TxFrame.GetRange(3, TxLength - 2); }
        }

        public byte TxChecksum
        {
            get { return TxFrame[TxLength - 1]; }
        }

        private byte[] txFrame;

        private bool successfull;
        public bool Successfull
        {
            get
            {
                return successfull;
            }
            set
            {
                if(successfull != value)
                {
                    successfull = value;
                    this.OnPropertyChanged();
                }
            }
        }


        public DataHandler()
        {
            txFrame = new byte[4] { 0, 0, 0, 0 };
            aTimer = new Timer(MAX_TIMER_TIME);
            watch = new Stopwatch();
            CommandManager.Instance.Init();
            InterfaceWrapper.Instance.SerialPort.DataReceived += OnSerialPortReceived;
        }

        public void InitializeSensor(InitType type, byte address, Int32 serialNumber = 0)
        {
            if (SensorContainer.GetSensor(address) != null )
            {
                MessageBox.Show("Sensoraddress already used");
                return;
            }

            foreach(Sensor temp in SensorContainer.SensorList)
            {
                if(temp.Serialnr == serialNumber)
                {
                    MessageBox.Show("Sensor with the same SerialNumber already initalized");
                    return;
                }
            }

            byte[] frame;

            if (type == InitType.INIT_TO_ONE_DEVICE)
            {
                Sensor.COM_ADDR_SET_ONE_TX initStruct = new Sensor.COM_ADDR_SET_ONE_TX();
                initStruct.Address = address;
                frame = createFrame(initStruct, 0xFF, 0x20);
            }
            else
            {
                Sensor.COM_ADDR_SET_TO_SN_TX initStruct = new Sensor.COM_ADDR_SET_TO_SN_TX();
                initStruct.Address = address;
                if (serialNumber == 0)
                {
                    MessageBox.Show("Serialnumber is missing");
                    return;
                }
                initStruct.SerialNumber = serialNumber;
                frame = createFrame(initStruct, 0x00, 0x22);
            }

            setTxFrame(frame);
            InterfaceWrapper.Instance.SerialPort.SendData(frame);
            initalisationFlag = true;
            initialisationType = type;
        }

        public void StartDataTransfer(Sensor sensor, byte commandid)
        {
            if (sensor == null)
            {
                MessageBox.Show("No such sensor");
                return;
            }

            Command command = sensor.getCommand(commandid);

            if (command == null)
            {
                MessageBox.Show("Command does not exist");
                return;
            }

            foreach (KeyValuePair<CommandAttribute, Command> pair in sensor.CommandList)
            {
                if (pair.Value == command)
                {
                    timeout = pair.Key.Timeout;
                    transmission = pair.Key.Transmission;
                    break;
                }
            }
            tempSensor = sensor;

            if (SensorContainer.GetSensor(sensor.Address) != null)
            {
                byte[] endFrame = createFrame(command, sensor.Address, commandid);

                setTxFrame(endFrame);
                if (true)
                {
                    InterfaceWrapper.Instance.SerialPort.SendData(txFrame);
                }
            }
            else
            {
                MessageBox.Show("Sensor not yet initialized");
            }
        }

        private byte[] createFrame(Command command, byte address, byte commandId)
        {
            byte[] data = MarshalHelper.Serialize(command);
            byte[] frame = new byte[4 + data.Length];
            frame[0] = address;
            frame[1] = (byte)frame.Length;
            frame[2] = commandId;
            Buffer.BlockCopy(data, 0, frame, 3, data.Length);
            frame[frame.Length - 1] = GenerateChecksum(frame);
            return frame;
        }

        public void OnSerialPortReceived(object sender, ComDataRxEvent e)
        {

                byte[] data = e.Data;
                setRxFrame(data);

        }

        public void setTxFrame(byte[] _txFrame)
        {
            Successfull = false;
            txFrame = _txFrame;
            aTimer.Elapsed += OnTimedEvent;
            aTimer.AutoReset = false;
            aTimer.Start();
            watch.Start();
        }

        public void setRxFrame(byte[] _rxFrame)
        {
            if (framePartPendingFlag)
            {
                byte[] newTempFrame = new byte[tempFrame.Length + _rxFrame.Length];
                tempFrame.CopyTo(newTempFrame, 0);
                _rxFrame.CopyTo(newTempFrame, tempFrame.Length);
                framePartPendingFlag = false;
                setRxFrame(newTempFrame);
            }
            else if (!checkMinLength(_rxFrame))
            {
                tempFrame = _rxFrame;
                framePartPendingFlag = true;
            }
            else if (!checkBit(_rxFrame))
            {
                tempFrame = _rxFrame;
                framePartPendingFlag = true;
            }
            else
            {
                framePartPendingFlag = false;
                aTimer.Stop();
                watch.Stop();
                answertime_milli = watch.ElapsedMilliseconds;

                if (!initalisationFlag)
                {
                    if (checkAll(_rxFrame))
                    {
                        writeCommandToSensor(_rxFrame);
                    }
                }
                else
                {
                    createSensorAfterInitialization(_rxFrame);
                }
            }
        }


        private void writeCommandToSensor(byte[] frame)
        {
            Command expCommand = CommandManager.Instance.GetRxCommand(tempSensor.GetType(), TxCommand);
            Command command = MarshalHelper.Deserialize(expCommand, frame.GetRange(3, frame[1] - 2));
            tempSensor.setCommand(command);
        }
        private void createSensorAfterInitialization(byte[] frame)
        {
            if (initalisationFlag && initialisationType == InitType.INIT_TO_ONE_DEVICE)
            {
                Sensor.COM_ADDR_SET_ONE_RX expCommand = new Sensor.COM_ADDR_SET_ONE_RX();
                Sensor.COM_ADDR_SET_ONE_RX command = (Sensor.COM_ADDR_SET_ONE_RX)MarshalHelper.Deserialize(expCommand, frame.GetRange(3, frame[1] - 2));
                Sensor tempSensor = Sensor.GetSensorInstance(command.SerialNumber, command.Address, command.SensorName, command.SensorSubName, command.dataStructType, command.dataStructSubType,command.pcbVersion,command.firmware);
                tempSensor.setCommand(command);
                SensorContainer.AddSensor(tempSensor);
                initalisationFlag = false;
            }
            else
            {
                Sensor.COM_ADDR_SET_TO_SN_RX expCommand = new Sensor.COM_ADDR_SET_TO_SN_RX();
                Sensor.COM_ADDR_SET_TO_SN_RX command = (Sensor.COM_ADDR_SET_TO_SN_RX)MarshalHelper.Deserialize(expCommand, frame.GetRange(3, frame[1] - 2));
                if (command == null)
                {
                    MessageBox.Show("Sensor not answering");
                }
                else {
                    Sensor tempSensor = Sensor.GetSensorInstance(command.SerialNumber, command.Address, command.SensorName, command.SensorSubName, command.dataStructType, command.dataStructSubType, command.pcbVersion, command.firmware);
                    tempSensor.setCommand(command);
                    SensorContainer.AddSensor(tempSensor);
                    initalisationFlag = false;
                }
            }
        }


        public void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            framePartPendingFlag = false;
        }

    }

0 个答案:

没有答案