當我嘗試通過.NET框架訪問串行端口時,我觀察到一些奇怪的行爲。我所做的是循環所有可用的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();
}
這也可能是我的計算機上的驅動程序的問題,不過,我可以做些什麼來avoide應用程序?實際上,我可以趕上 AppDomain.CurrentDomain.UnhandledException(object sender, UnhandledExceptionEventArgs e)
但隨後的e.ExceptionObject.IsTerminating
是true
和應用程序反正關閉...
編輯:
正如我所說的,我不能直接捕獲該異常,我在這裏發表的是堆棧跟蹤來自傳遞給AppDomain.CurrentDomain.UnhandledException
事件的異常對象。我可以登錄這一點,但因爲這個異常對象IsTerminating
雖然研究涉及到SerialPort類中的內存泄漏問題,我碰到這個職位後來我不能做任何有用它
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()
堆棧跟蹤會有幫助 – leppie
該線程在端口打開時啓動。我想不知道當另一個程序也試圖訪問端口時,它不是非常安全。這可能是由於'SerialPort'是一個'Component',可能需要在Windows消息循環下運行,才能使用WinForms應用程序。 – leppie
這個測試應用程序只是一個控制檯應用程序,目標應用程序是一個wpf應用程序,其中發生相同的錯誤。稍後我會在表單應用程序中嘗試此代碼段。然而,你有沒有任何參考指向我如何在消息循環下運行此代碼段(給出一個wpf應用程序)? –