1

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

现在奇怪的行为:有时应用程序会因 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()
4

1 回答 1

1

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

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

您如何在此期间解决它?简单的。在调用 SerialPort.Open() 之前,只需调用 CreateFile 并将 SetCommState 的 fAbortOnError 设置为 false 即可打开串行端口。现在您可以安全地打开串口,而不必担心它可能会抛出 IOException。

于 2014-07-22T03:14:51.413 回答