奇怪的SerialPort行为导致应用程序崩溃

时间:2014-01-06 11:04:18

标签: c# .net serial-port objectdisposedexception

我在尝试通过.NET框架访问SerialPort时发现了一些奇怪的行为。我所做的是遍历所有可用的COM端口,发送字符串,读取响应并关闭端口。目的是检查设备插入的端口。

现在奇怪的行为:有时App崩溃了ObjectDisposedException,有时候没有。这种观察的随机性以及我无法捕获ObjectDisposedException这一事实使我相信问题必定发生在我无法控制的另一个方面。

我的问题是:什么可能导致此异常,我该怎么做才能避免它?

这是我的小测试应用程序的完整代码,在三次试验中随机崩溃:

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();
}

它也可能是我的计算机上的驱动程序问题,但是,我还能做些什么来避免使用该应用程序?我真的能抓住了 AppDomain.CurrentDomain.UnhandledException(object sender, UnhandledExceptionEventArgs e)e.ExceptionObject.IsTerminatingtrue,应用程序仍会关闭...

编辑:

正如我所说,我无法直接捕获异常,我在这里发布的是来自传递给AppDomain.CurrentDomain.UnhandledException事件的异常对象的堆栈跟踪。我可以记录这个但是因为这个异常对象IsTerminating我无法用它做任何有用的事情

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 个答案:

答案 0 :(得分:1)

在研究与SerialPort类相关的内存泄漏问题时,我遇到了这篇文章: .NET SerialPort Woes

你提到了一个ObjectDisposedException,这篇文章主要是关于IOExceptions的,所以我不确定你的问题是否相关。但是,在本文的最后,您可以尝试使用IOException的解决方案:

  

你如何在过渡期间修复它?简单。在调用SerialPort.Open()之前,只需通过调用CreateFile和SetCommState的fAbortOnError为false来打开串口。现在您可以安全地打开串口,而不必担心它可能会抛出IOException。