public static void SendInteleconCommandAsync(this IMonoChannel channel, IInteleconCommand command,
                                                     ObjectAddress objectAddress, int timeout, Action <ISendResultWithAddress> onComplete, IoPriority priority)
        {
            var sendingItem = new AddressedSendingItem {
                Address       = objectAddress,
                WaitTimeout   = timeout,
                AttemptsCount =
                    1, // �� �����, ������� ��������� ������������� � �������, ������ ������� �� 8 ���� ������ ���� ��������� �������

                // 2013.07.26 - ���� ������, ��� 0x00FF ������ ������ ����������� ��� ������ � ������
                // 2013.08.15 - ������ ��� ������ � SerialNumber
                Buffer = command.Serialize()
                         .GetNetBuffer(
                    (ushort)(objectAddress.Way == NetIdRetrieveType.SerialNumber ||
                             objectAddress.Way == NetIdRetrieveType.OldProtocolSerialNumber
              ? 0x00FF
              : objectAddress.Value), command.Code)
            };

            channel.AddCommandToQueueAndExecuteAsync(
                new QueueItem {
                SendingItems = new List <IAddressedSendingItem> {
                    sendingItem
                },
                OnComplete = results => {
                    if (results == null)
                    {
                        onComplete(new SendingResultWithAddress(null, new Exception("������ ������� �� ���������� (is null)"),
                                                                null, 0));
                    }
                    else if (results.Count == 1)
                    {
                        var bytes             = results[0].Bytes;
                        var externalException = results[0].ChannelException;
                        if (externalException == null)
                        {
                            Log.Log("��� �����: " + bytes.ToText());
                            Exception internalException = null;
                            byte[] infoBytes            = null;
                            ushort addressInReply       = 0;
                            try {
                                // ������������ ��� ��������� � ������� ����� ������
                                bytes.CheckInteleconNetBufCorrect((byte)(sendingItem.Buffer[2] + 10), null);
                                addressInReply = (ushort)(bytes[3] * 0x100 + bytes[4]);
                                Log.Log("����� ���������: " + addressInReply + " ��� 0x" + addressInReply.ToString("X4"));
                                infoBytes = bytes.GetInteleconInfoReplyBytes();
                                Log.Log("����� ��������������� ����: " + infoBytes.ToText());
                            }
                            catch (Exception ex) {
                                Log.Log(ex.ToString());
                                internalException = ex;
                            }
                            finally {
                                onComplete(new SendingResultWithAddress(infoBytes, internalException, results[0].Request,
                                                                        addressInReply));
                            }
                        }
                        else
                        {
                            onComplete(new SendingResultWithAddress(null, externalException, results[0].Request, 0));
                        }
                    }
                    else
                    {
                        onComplete(new SendingResultWithAddress(null,
                                                                new Exception("�������� ���������� �������: " + results.Count + " (�������� ���� �����)"), null,
                                                                0)); // ��� ���� �� ����������, ����� ������ ������ ����������, �������, ������� �� ��������
                    }
                }
            }, priority);
        }
        public void AddCommandToQueueAndExecuteAsync(object item, IoPriority priority)
        {
            _queueWorker.AddWork(() => {
                try {
                    QueueLength++;
                    NotifyQueueCountChanged();
                    IsTaskExecuting = true;
                    if (item is QueueItem queueItem)
                    {
                        var addressItem      = queueItem;
                        var progressItemPart = new List <ISendResult>();
                        foreach (var sendItem in addressItem.SendingItems)
                        {
                            Exception exc = null;
                            byte[] result = null;
                            try {
                                var lastBadTime = _linkQualityStorage.GetLastBadTime(sendItem.Address);
                                var nowTime     = DateTime.Now;

                                if (lastBadTime.HasValue && nowTime - lastBadTime.Value < _onlineCheckTime)
                                {
                                    exc = new Exception(lastBadTime.Value.ToString("yyyy.MM.dd-HH:mm:ss") + " с объектом по адресу " +
                                                        sendItem.Address +
                                                        " не получалось установить связь, так что еще рано с ним связываться (прошло времени: " +
                                                        (nowTime - lastBadTime.Value).TotalSeconds.ToString("f2") +
                                                        " сек, а должно пройти: " + _onlineCheckTime.TotalSeconds.ToString("f2") +
                                                        " сек)");
                                }
                                else
                                {
                                    Log.Log("Запрос в сеть БУМИЗ для объекта по адресу" + sendItem.Address);
                                    result = AskForData(sendItem.Address, sendItem.Buffer, sendItem.AttemptsCount,
                                                        sendItem.WaitTimeout);
                                    _linkQualityStorage.SetLastBadTime(sendItem.Address, null);
                                    Log.Log("Связь с объектом по адресу " + sendItem.Address +
                                            " была установлена, время последнего неудачного обмена обнулено");
                                }
                            }
                            catch (Exception ex) {
                                var lastBadTime = DateTime.Now;
                                _linkQualityStorage.SetLastBadTime(sendItem.Address, lastBadTime);
                                exc = ex;
                                Log.Log("Во время обмена произошла ошибка, поэтому время неудачного обмена установлено в значение: " +
                                        lastBadTime.ToString("yyyy.MM.dd-HH:mm:ss") + ", исключение: " + ex);
                            }
                            finally {
                                progressItemPart.Add(new SendingResult(result, exc, sendItem));
                            }
                        }

                        _notifyWorker.AddWork(() => addressItem.OnComplete(progressItemPart));
                    }
                    else if (item is IQueueRawItem)
                    {
                        Log.Log("Отправка произвольных данных в порт...");
                        var rawItem = item as IQueueRawItem;
                        var result  = new SendRawResultSimple();
                        try {
                            result.Bytes = _channelSimple.RequestBytes(rawItem.SendItem.SendingBytes.ToArray(),
                                                                       rawItem.SendItem.AwaitedBytesCount, 10);
                        }
                        catch (Exception ex) {
                            result.ChannelException = ex;
                        }

                        if (rawItem.OnSendComplete != null)
                        {
                            _notifyWorker.AddWork(() => rawItem.OnSendComplete(result));
                        }
                    }
                }
                catch (Exception ex) {
                    Log.Log("В задании для обработчика очереди обмена произошло исключение: " + ex);
                }
                finally {
                    //Thread.Sleep(100);
                    IsTaskExecuting = false;
                    QueueLength--;
                    NotifyQueueCountChanged();
                }
            }
                                 , (int)priority);
        }
Exemple #3
0
        public void SendDataAsync(string name, IInteleconCommand cmd, Action <ISendResultWithAddress> callback, IoPriority priority)
        {
            _sendQueueWorker.AddWork(() => {
                try {
                    var bumizObj     = GetBumizObject(name);
                    var bumizChannel = GetBumizChannel(bumizObj.ChannelName);

                    bumizChannel.SendInteleconCommandAsync(cmd, bumizObj.Address, bumizObj.Timeout, result => _notifyQueueWorker.AddWork(() => callback(result)), priority);
                }
                catch (Exception ex) {
                    Log.Log("Во время отправки команды возникло исключение: " + ex);
                    _notifyQueueWorker.AddWork(() => callback(new SendingResultWithAddress(null, ex, null, 0)));
                }
            });
        }