/// <summary>
        /// Захватить коммуникационный порт
        /// </summary>
        /// <param name="deviceId">Идентификатор устройства</param>
        /// <param name="portName">Имя порта</param>
        /// <param name="waitIfCaptured">Ожидать освобождения порта</param>
        /// <param name="waitTime">Время, в течение которого ожидать освобождение</param>
        public EasyCommunicationPort CapturePort(string deviceId, string portName,
                                                 bool waitIfCaptured, TimeSpan waitTime)
        {
            CheckSerialPortName(portName);
            SerialPortsHelper helper = _serialPortsPool[portName];

            // попытка захвата порта
            TimeSpan timeElapsed = new TimeSpan();

            do
            {
                if (string.IsNullOrEmpty(helper.DeviceId) || string.Compare(helper.DeviceId, deviceId) == 0)
                {
                    lock (_portsLocker)
                    {
                        helper.DeviceId = deviceId;
                    }
                    return(helper.Port);
                }
                else if (waitIfCaptured)
                {
                    // ждем освобождения порта
                    Thread.Sleep(50);
                    TimeSpan ts = new TimeSpan(0, 0, 0, 0, 50);
                    timeElapsed.Add(ts);
                }
            }while (waitIfCaptured && (timeElapsed < waitTime));

            // порт занят другим устройством
            ThrowPortIsBusy(portName, helper.DeviceId);
            return(null);
        }
        /// <summary>
        /// Получить доступ к порту из пула
        /// </summary>
        /// <param name="deviceId">Идентификатор устройства</param>
        /// <param name="portName">Имя порта</param>
        /// <returns>Порт из пула</returns>
        public EasyCommunicationPort GetPort(string deviceId, string portName)
        {
            CheckSerialPortName(portName);
            SerialPortsHelper helper = _serialPortsPool[portName];

            if (string.Compare(helper.DeviceId, deviceId) == 0)
            {
                return(helper.Port);
            }
            else
            {
                ThrowPortIsBusy(portName, helper.DeviceId);
                return(null);
            }
        }
        /// <summary>
        /// Заполнение пула портов
        /// </summary>
        private void UpdateSerialPortsPool()
        {
            // заполняем пул портов
            var names = new List <string>();

            names.AddRange(SerialPortsEnumerator.Enumerate());
            names.AddRange(SerialPortsEnumerator.EnumerateLPT());
            foreach (string portName in names)
            {
                if (!_serialPortsPool.ContainsKey(portName))
                {
                    SerialPortsHelper helper = new SerialPortsHelper(portName);
                    _serialPortsPool.Add(portName, helper);
                }
            }
        }
        /// <summary>
        /// Освободить коммуникационный порт
        /// </summary>
        /// <param name="deviceId">Идентификатор устройства</param>
        /// <param name="portName">Имя порта</param>
        public void ReleasePort(string deviceId, string portName)
        {
            CheckSerialPortName(portName);
            SerialPortsHelper helper = _serialPortsPool[portName];

            // попытка освобождение порта
            if (string.IsNullOrEmpty(helper.DeviceId) || string.Compare(helper.DeviceId, deviceId) == 0)
            {
                lock (_portsLocker)
                {
                    helper.DeviceId = string.Empty;
                }
            }
            else
            {
                // порт занят другим устройством
                ThrowPortIsBusy(portName, helper.DeviceId);
            }
        }