Brad
Brad

Reputation: 12253

I don't know where to catch this error: Access to the port is denied

I'm using a serial port with a Serial Object and sometimes I get this error.

UnauthorizedAccessException: Access to the port is denied.

with a stack trace of:

   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.Ports.SerialStream.Finalize()

It doesn't occur at any line of code (within my code at least) so I'm not sure how to trap it. I figure what is happening is the serial (via USB) port is being physically unplugged/disconnected for a split second and is throwing everything into whack.

I can click Continue on the error which I'm debugging and everything is fine. Communication with the serial device is flawless otherwise. But when the program is actually published, deployed and running it gives me several error messages and is all ugly for the user.

How can I trap this error/what can I do to prevent it in the first place?

Thanks

Upvotes: 2

Views: 2405

Answers (1)

prairiehat
prairiehat

Reputation: 181

I encounter the same exception and stack trace in my WinForms application when used with a USB-to-serial converter. I can consistently recreate it by

  • creating an instance of SerialPort
  • calling SerialPort.Open,
  • removing the USB-to-serial converter,
  • closing the app (which calls SerialPort.Dispose)

My suspicion is that the exception is being thrown in SerialPort's finalizer. Others have experienced the same symptoms - see here.

To work around I followed the recommendation of Kuno and KyferEz (from link above) to implement my own ExtSerialPort. This inherits SerialPort, overrides the Dispose method and (using reflection) disposes the SerialPort's internalSerialStream.

Imports System.IO.Ports

Public Class ExtSerialPort
    Inherits SerialPort

    Public Sub New()
        MyBase.new()
    End Sub

    Public Sub New(ByVal portName As String)
        MyBase.New(portName)
    End Sub

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)

        Dim mytype As Type = GetType(SerialPort)
        Dim field As Reflection.FieldInfo = mytype.GetField("internalSerialStream", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
        Dim stream As Object = field.GetValue(Me)

        If stream IsNot Nothing Then
            Try
                stream.Dispose()
            Catch ex As Exception
            End Try
        End If

        MyBase.Dispose(disposing)
    End Sub

End Class

Upvotes: 1

Related Questions