В SerialPort доступ запрещен при вызове Close, но не Dispose - PullRequest
0 голосов
/ 14 февраля 2019

ОБНОВЛЕНИЕ 1

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

Мне удалось повторить ошибку на моем устройстве, создав замыкание на землю на одной из линий данных.Я использую FT230x на своем устройстве и обнаружил, что если я замкну Reset Pin, то связь может возобновиться, однако теперь я получаю другое исключение из своего приложения, как только я делаю это.Таким образом, технически мое приложение теперь будет повторно подключаться при перезапуске, что является улучшением, когда, как и раньше, мне приходилось физически отключать и подключать мое устройство.Новое исключение ниже:

System.ObjectDisposedException
  HResult=0x80131622
  Message=Safe handle has been closed
  Source=mscorlib
  StackTrace:
   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   at Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
   at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Новая странность в том, что стек вызовов не содержит никакого моего кода, а Visual Studio не позволяет мне отследить его до моего кода.

ОРИГИНАЛЬНЫЙ ПОСТ

У меня есть устройство, которое выдает мне IOException для SerialPort.Write, а затем, когда я пытаюсь закрыть порт, я получаю UnauthorizedAccessException.После этого я могу распоряжаться последовательным портом без исключения, но попытки повторно открыть порт приводят к UnauthorizedAccessException.Мое настоящее замешательство возникает, когда я продолжаю читать, что Dispose и Close должны делать одно и то же.Можно ли как-нибудь восстановиться после этого без перезапуска программы (или, в некоторых случаях, компьютера)?

В моем проекте я управляю несколькими устройствами, которые либо используют один и тот же Com-порт, либо используют уникальный com-порт.Поэтому у меня есть менеджер, который управляет моими устройствами, находит их порты и создает диспетчер портов для этих устройств.Иногда устройства отключаются, и когда это происходит, я закрываю и располагаю com-порт и диспетчер com-портов.Ниже приведен мой код:

private void DisposeComPort()
{
    if (ComPort != null)
    {
        string message = "Disposing Com Port.";
        try
        {
            ComPort.DataReceived -= ComPort_DataReceived;
            ComPort.ErrorReceived -= ComPort_ErrorReceived;
            message += " Com Port Events Unsubscribed.";

        }
        catch (Exception ex)
        {
            HandleException(this, ex, "Exception attempting to remove Handlers for on " + this.ToString() + ".");

        }
        try
        {
            if (ComPort.IsOpen)
            {
                ComPort.Close(); message += " Com Port Closed.";
            }
        } catch(Exception ex)
        {
            HandleException(this, ex, "Exception attempting to close on " + this.ToString() + ".");
        }
        try
        {
            ComPort.Dispose(); message += " Com Port Disposed.";
        } catch (Exception ex)
        {
            HandleException(this, ex, "Exception attempting to Dispose Com Port on " + this.ToString() + ".");
        }
        ComPort = null;
        LogMessage(this, message);
    }
}

У меня есть одно устройство, которое каждые пару дней выдает мне сообщение «System.IO.IOException: устройство, подключенное к системе, не работает» при попытке ComPort.Write.().Когда это происходит, я пытаюсь избавиться от моего com-порта.При нормальных обстоятельствах я смог бы закрыть порт и снова открыть его, однако в этом случае мой код не закрывается и удаляется, однако, когда мой диспетчер устройств пытается повторно открыть com-порт, я продолжаю получать UnauthorizedAccessException.Ниже мой журнал исключений.

11:26:35.862, Exception Sending Com Packet to Device 34 on ModbusPortManager Port COM4 Created 6:30:48 AM.
System.IO.IOException: A device attached to the system is not functioning.

   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.SerialStream.EndWrite(IAsyncResult asyncResult)
   at System.IO.Ports.SerialStream.Write(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
   at System.IO.Ports.SerialPort.Write(Byte[] buffer, Int32 offset, Int32 count)
   at ModbusPortManager.TransmitPacket(IModbusDevice device, ComPacket packet, Int32 packetIndex) in Classes\ModbusPortManager.cs

-----------------------------------------------------------------------------

11:26:35.880, Disposing Timers. Stopped MessageReceived EventWaitHandle. Stopped PacketTimeoutTimer Timer. Stopped RetransmitTimer Timer. Stopped AgePrioritizerTimer Timer. Stopped 4/4. ~ ModbusPortManager Port COM4 Created 6:30:48 AM Disposed

-----------------------------------------------------------------------------

11:26:35.894, Exception attempting to close on ModbusPortManager Port COM4 Created 6:30:48 AM Disposed.
System.UnauthorizedAccessException: Access to the port is denied.
   at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
   at System.IO.Ports.InternalResources.WinIOError()
   at System.IO.Ports.SerialStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.IO.Ports.SerialPort.Dispose(Boolean disposing)
   at System.IO.Ports.SerialPort.Close()
   at ModbusPortManager.DisposeComPort() in Classes\ModbusPortManager.cs

-----------------------------------------------------------------------------

11:26:35.904, Disposing Com Port. Com Port Events Unsubscribed. Com Port Disposed. ~ ModbusPortManager Port COM4 Created 6:30:48 AM Disposed

-----------------------------------------------------------------------------

11:26:36.934, Port Manager Created. ~ ModbusPortManager Port COM4 Created 11:26:36 AM

-----------------------------------------------------------------------------

11:26:36.947, Exception Testing on ModbusPortManager Port COM4 Created 11:26:36 AM

System.UnauthorizedAccessException: Access to the port 'COM4' is denied.
   at ModbusPortManager.OpenPort() in Classes\ModbusPortManager.cs
   at ModbusPortManager.TestPort() in Classes\ModbusPortManager.cs

-----------------------------------------------------------------------------

1 Ответ

0 голосов
/ 15 февраля 2019

В конечном итоге мы решили проблему System.ObjectDisposedException, реализовав решение из ObjectDisposedException при закрытии SerialPort в .Net 2.0 , а класс из http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html

Класс SerialPortFixer выбрасывает недопустимыйпараметров на некоторых портах, но на моем устройстве это не так, и больше не возникает исключение, которое приводит к сбою программы при повторном подключении.

...