尝试通过 .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.IsTerminating
是true
并且应用程序无论如何都会关闭......
编辑:
正如我所说,我无法直接捕获异常,我在这里发布的是传递给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()