views:

50

answers:

1

I have a WPF/C# app that is launched as part of the "Startup" group on a Windows Embedded Standard machine. One of the first things the app does (in its static App() method) is create a new SerialPort object for COM1. COM1 is a hardwired serial port, not a USB virtual port or anything like that.

My problem is that every so often (maybe 1 out of 12) on startup, I get an exception: System.UnauthorizedAccessException: Access to the port 'COM1' is denied.

There are no other applications using this port. Also, when I relaunch the app following this error, it grabs the port just fine. It's as if the com port isn't ready/set up for my app sometimes.

I'm clueless on this one! Any insight is appreciated!

UPDATE: I added a call to SerialPort.GetPortNames() and printout all available ports before attempting to open the port. In the failure case COM1 is indeed THERE! So, it's not that the port isn't ready. It looks like something in Windows is actually grabbing the port temporarily and blocking me.

+1  A: 

A few responders at Microsoft seem to think that the kernel grabs COM1 temporarily at startup for debug reasons. They say the best approach is to essentially work around the issue... catch the exception and try again. Boooo.

I modified my code to retry opening the port a few times before giving up, which seems to work around this issue.

Old code:

_port = new SerialPort(port, 9600, Parity.None, 8, StopBits.One);                                 
_port.Open();   // This can throw an exception

New code:

const int PORT_OPEN_MAX_ATTEMPTS = 10;
bool portOpened = false;
int portOpenAttempts = 0;                     

            _port = new SerialPort(port, 9600, Parity.None, 8, StopBits.One);                      

            while (!portOpened)
            {
                try
                {
                    _port.Open();
                    portOpened = true;      // Only get here if no exception
                }

                catch (UnauthorizedAccessException ex)
                {
                    // Log, close, then try again
                    if (portOpenAttempts++ < PORT_OPEN_MAX_ATTEMPTS)
                    {                       
                        _logger.Debug("Port UnauthorizedAccessException. Attempt - " + portOpenAttempts);

                        Thread.Sleep(100);
                        _port.Close();
                    }

                    else
                    {
                        throw(ex);
                    }
                }
            }
Tim