SerialPort UnauthorizedAccessException - PullRequest
10 голосов
/ 08 сентября 2011

Иногда некоторые из моих интеграционных тестов не выполняются с вышеприведенным сообщением.Я использую код ниже, чтобы подготовить порт.

            for(int i = 0; i < 5; i++)
            {
                try
                {
                    port.Open();
                    if (port.IsOpen)
                        break;
                }
                catch (Exception e)
                {
                    try
                    {
                        port.Close();
                    }
                    catch (Exception)
                    {}
                    Thread.Sleep(300);
                }
            }   

Я предполагаю, что, поскольку текущий поток не может блокировать порт (потому что он попытается закрыть его), это должен быть другой поток или процесс, который был остановлен без очистки должнымодин из других тестов - ничто другое не получает доступ к этому порту).Есть ли способ сбросить состояние SerialPort, чтобы новый поток / процесс мог снова получить к нему доступ?

Спасибо,

Ричард

Ответы [ 4 ]

16 голосов
/ 08 сентября 2011

Это недостаток в классе SerialPort, он использует внутренний вспомогательный поток для ожидания событий в порту.Источник событий DataReceived, PinChanged и ErrorReceived.Недостаток в реализации метода Close (), он не ожидает завершения этого вспомогательного потока.Это требует времени, точное количество времени не предсказуемо и может быть много секунд, когда машина особенно занята.Физический порт не закрывается до тех пор, пока это не произойдет, открывая порт до того, как поток выйдет из бомб с исключением «порт уже используется».Тот, который вы получаете.Спать в течение 300 мсек, таким образом, недостаточно хорошо.

Обычно это не проблема, последовательные порты не являются разделяемыми устройствами.Закрытие последовательного порта и не выход из вашей программы опасно, другой процесс может украсть порт.Также дает вам это исключение, когда вы пытаетесь открыть его снова.Обычная практика - открывать порт при запуске приложения и не закрывать его до тех пор, пока оно не завершится.

5 голосов
/ 28 ноября 2013

Я обычно проверяю, что порт закрыт, прежде чем я создаю экземпляр последовательного порта.Это поможет, если вы остановите отладочный код, не закрыв последовательный порт.Также вам следует подождать 250 мсек после открытия или закрытия порта, прежде чем продолжить работу с кодом.

try
        {
            if ((m_SerialPort != null))
            {
                if (m_SerialPort.IsOpen)
                {
                    m_SerialPort.Close();
                }
             }
             m_SerialPort = new SerialPort(portName, dataRate, parity, databits, stopBits.One);
             m_SerialPort.Open();
             if (!m_SerialPort.IsOpen)
             {
                 MessageBox.Show(string.Concat(portName, " failed to open"));
             }
         }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
2 голосов
/ 08 сентября 2011

Я не вижу, где вы закрываете порт.

Проблема для меня не в этом (даже если вам нужно немного изменить код), но, вероятно, вы звоните port.Open();, когда порт еще открыт

Из MSDN

На один объект SerialPort может существовать только одно открытое соединение.

(я не могу сказать вам почему, потому что у меня недостаточно информации). Имейте также в виду, что метод close требует некоторого времени для фактического закрытия порта, фактически вы должны блокировать основной поток, пока порт не будет закрыт. (возможно, используя Thread.Join)

Из MSDN

Лучшая практика для любого приложения - подождать некоторое время после вызова метода Close, прежде чем пытаться вызвать метод Open, так как порт не может быть закрыт мгновенно.

для получения дополнительной информации

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.open.aspx

0 голосов
/ 01 февраля 2015

GC.SuppressFinalize и GC.ReRegisterForFinalize должны вызываться с передачей свойства экземпляра SerialPort BaseStream в качестве параметра, а не только с экземпляром SerialPort.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...