2014-01-06 169 views
0

當我嘗試通過.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.IsTerminatingtrue和應用程序反正關閉...

編輯:

正如我所說的,我不能直接捕獲該異常,我在這裏發表的是堆棧跟蹤來自傳遞給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() 
+1

堆棧跟蹤會有幫助 – leppie

+0

該線程在端口打開時啓動。我想不知道當另一個程序也試圖訪問端口時,它不是非常安全。這可能是由於'SerialPort'是一個'Component',可能需要在Windows消息循環下運行,才能使用WinForms應用程序。 – leppie

+0

這個測試應用程序只是一個控制檯應用程序,目標應用程序是一個wpf應用程序,其中發生相同的錯誤。稍後我會在表單應用程序中嘗試此代碼段。然而,你有沒有任何參考指向我如何在消息循環下運行此代碼段(給出一個wpf應用程序)? –

回答

1

.NET SerialPort Woes

你提到的ObjectDisposedException,文章主要是關於IOExceptions,所以我不確定你的問題是否相關。但是,在文章的最後,您可以嘗試使用IOException的解決方案:

如何在過渡期內修復它?簡單。在調用SerialPort.Open()之前,只需調用CreateFile和SetCommState的fAbortOnError爲false來打開串口。現在您可以安全地打開串口而不用擔心它可能會拋出IOException。

+0

感謝您的回覆。幸運的是,我們找到了一種完全避開串口的方法,並使用更穩定的tcp連接方式。坦白說,我不會再找時間去調查這個了...... –