Ошибка связи последовательного порта: "Запрошенный ресурс используется".

Вот код, который считывает данные из последовательного порта. Чтобы все было просто, сделайте это нажатием кнопки;

    private System.IO.Ports.SerialPort serialPort;

    private void button1_Click(object sender, EventArgs e)
    {
        if (serialPort == null)
            serialPort = new SerialPort("COM7", 4800, Parity.None, 8, StopBits.One);
            //COM7 is hard coded just for the sake of example

        if (!serialPort.IsOpen)
            serialPort.Open();

        textBox1.AppendText(serialPort.ReadExisting());
    }

Код работает отлично, если мой ноутбук не заснет. Когда система просыпается от сна, объект serialPort не null, а serialPort.IsOpen возвращает false, и я получаю сообщение об ошибке, "Запрошенный ресурс используется." while вызов serialPort.Open(). Во внутреннем исключении ничего нет. enter image description here

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

        if (!serialPort.IsOpen)
        {
            try
            {
                serialPort.Open();
            }
            catch
            {
                serialPort.Close();
                serialPort.Dispose();
                serialPort = null;

                serialPort = new SerialPort("COM7", 4800, Parity.None, 8, StopBits.One);
                serialPort.Open();
            }
        }

Я также пробовал событие serialPort.DataReceived, но событие не запускается после того, как система проснулась от сна.

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

Ответы

Ответ 1

Как я предложил в комментарии, обходной путь можно сделать, используя событие SystemEvents.PowerModeChanged, чтобы обнаружить, когда система собирается приостановить. Когда это состояние обнаружено, вам нужно закрыть последовательный порт и снова открыть его, когда операционная система вот-вот вернется из приостановленного состояния.

hamad подтвердил, что это обходное решение работает.

Вот код.

SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;

void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
    if (e.Mode != PowerModes.Resume)
        serialPort.Close();
}

Также обратите внимание на документацию события:

Внимание

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