Strange SerialPort behavior crashes application

1.8k views Asked by At

I observe some strange behavior when trying to access the SerialPort via .NET framework. What I do is loop over all available com ports, send a string, read the response and close the port. The purpose is to check on which port a device is plugged.

Now the strange behavior: sometimes the App crashes with an ObjectDisposedException and sometimes not. The randomness of this observation and the fact that I cannot catch the ObjectDisposedException makes me believe that the problem must occur in another thread out of my control.

My question is: what could cause this Exception and what can I do to avoid it?

This is the full code of my little test app that crashes randomly two out of three trials:

private static void Main(string[] args)
{
    try
    {
        var portnames = SerialPort.GetPortNames();
        foreach (var portName in portnames)
        {
            try
            {
                Console.WriteLine("Try Port {0}...", portName);
                var serial = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One)
                    {
                        WriteTimeout = 500,
                        ReadTimeout = 500,
                        Handshake = Handshake.XOnXOff
                    };

                serial.Open();
                serial.WriteLine("foo bar");
                Thread.Sleep(500);
                var responseBuffer = serial.ReadLine();
                serial.Close();

                Console.WriteLine(" >> Port {0} responded: {1}", portName, responseBuffer);
            }
            catch (Exception ex)
            {
                Console.WriteLine(" >> Port {0} exception: {1}", portName, ex.Message);
            }
        }
    }
    catch (ObjectDisposedException ode)
    {
        // this never happens but the app crashes with an ObjectDisposedException
        Console.WriteLine("yea, got you!"); 
    }

    Console.WriteLine("finished checking ports...");
    Console.ReadKey();
}

It may also be a driver issue on my computer, but still, what could I do to avoid the app? I can actually catch the AppDomain.CurrentDomain.UnhandledException(object sender, UnhandledExceptionEventArgs e) but then the e.ExceptionObject.IsTerminating is true and the app shuts down anyways...

EDIT:

As I said, I cannot catch the exception directly, what I post here is the stack trace from the exception object that is passed to AppDomain.CurrentDomain.UnhandledException event. I can log this but since this exception object IsTerminating I cannot do anything useful with it.

bei System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
   bei System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   bei Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
   bei System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
   bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   bei System.Threading.ThreadHelper.ThreadStart()
1

There are 1 answers

1
Christoph On

While researching a memory leak problem related to the SerialPort class I came across this post: .NET SerialPort Woes

You mentioned an ObjectDisposedException, the article is mostly about IOExceptions so I'm not sure whether your problem is related. However, at the end of the article there is a solution for the IOException that you could try:

How do you fix it in the interim? Simple. Before you call SerialPort.Open(), simply open the serial port by calling CreateFile and SetCommState's fAbortOnError to false. Now you can safely open the serial port without worrying that it might throw an IOException.