2009-04-28 47 views
0

計算機通過物理COM1連接到測量設備。我有一個簡單的表單,我打開一個串口,告訴設備我還活着,有時候設備發送數據。 (每隔幾分鐘)打開的SerialPort崩潰C#應用程序

Thread _readThread = new Thread(Read); 
SerialPort _serialPort = new SerialPort("COM1", 9600); 
_serialPort.Parity = Parity.None; 
_serialPort.DataBits = 8; 
_serialPort.StopBits = StopBits.One; 
_serialPort.Handshake = Handshake.None; 
_serialPort.DtrEnable = true; 
_serialPort.Open(); 
_readThread.Start(); 
_serialPort.Write("#listening"); 

讀取功能(工作):

public void Read() 
{ 
    string message = _serialPort.ReadLine(); 
} 

大約一分鐘後,應用程序崩潰(即使調試)。它報告一個ObjectDisposedException(對於基礎流?)。該消息告訴SafeHandle已關閉。堆strace的低於:

在Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle HFILE,NativeOverlapped lpOverlapped的,的Int32 &指向lpNumberOfBytesTransferred,布爾BWAIT) 在System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent() 在System.Threading.ThreadHelper.ThreadStart_Context在System.Threading.ExecutionContext.Run(對象狀態) 在System.Threading.ThreadHelper.ThreadStart()(ExecutionContext中的ExecutionContext,ContextCallback回調,對象狀態) *

任何想法?這個問題被廣泛報道,但通常涉及與個人電腦脫離的設備。

+0

我知道SerialPort類在Mono上有一些問題。你在使用Mono還是MS .NET? – Skurmedel 2009-04-28 11:32:22

+0

MS .NET Framework 3.5 SP1 – 2009-04-28 11:34:15

+0

可能不是解決方案,但您打開之前調用Write。 – Skurmedel 2009-04-28 11:34:38

回答

1

這似乎是RS232電纜(適配器)導致底層串口流的崩潰。切換到FTDI電纜,工作。

查看.NET Framework源代碼幫助了很多。但我認爲拋出的ObjectDisposedException應該被SerialPort捕獲,而不是由用戶捕獲。

0

ObjectDisposedException意味着有人在對象上調用Dispose。啓動讀取線程後,你在做什麼?您在退出程序之前是否等待讀取線程完成?否則,可能讀取的線程仍然在程序退出時運行。

0

大約一年前,我曾經有過類似的事情發生在我身上。出於某種原因,讀取緩衝區末尾的某些字符會導致串行端口的C#接口自行關閉。它通常在\r\n位於緩衝區末尾時發生,儘管它也可能是其他一些字符。

剛剛購買了商用串口DLL的許可證。

祝你好運!

1

嘗試在閱讀前檢查IsOpen。

另外,是否有任何機會包含_serialPort的對象已被解除引用和垃圾收集?如果你從來沒有從另一個線程訪問_serialPort,請嘗試在Read()中將其設置爲一個私有變量。

0

你_serialPort聲明爲螺紋起始碼當地的SerialPort,那麼什麼是_serialPort在讀指()?

嘗試在Read()方法創建_serialPort對象,以確保它是在同一個線程的上下文。

0

1) Thread _readThread = new Thread(Read);

// is this a local definition of _readThread var in constructor? 
// if so, after some time gabbage collector clear this var from memory, a disposed object 
// shouldnot work (there is no such an object in memory). 
// The same with SerialPort local var 
// To work properly you should somewhere in class define a member 

class foo 
{ 
    // ... 
    Thread _readThread; 
    SerialPort _serialPort; 
    bool bRunningReadTrhead=false; 

    //... 

    // which is static or instanced, than 

    public foo() 
    { 
     // ... 
     _serialPort = new SerialPort("COM1", 9600); 
     _serialPort.Parity = Parity.None; 
     _serialPort.DataBits = 8; 
     _serialPort.StopBits = StopBits.One; 
     _serialPort.Handshake = Handshake.None; 
     _serialPort.DtrEnable = true; 
     _serialPort.Open(); 
     _readThread = new Thread(Read); 

     bRunningReadTrhead=true; 

     _readThread.Start(); 

     //... 
    } 

    // creates a thread which will live a long time in loop: 
    private void Read() 
    { 
     while(bRunningReadTrhead) 
     { 
      try 
      { 
       string message = _serialPort.ReadLine(); 
      } 
      catch(Exception e) 
      { 
      Console.Write(e); 
      } 
     } 

     // exits a worker thread when you set global bool in false 
    } 

    // ... 
} 

// if you do not set a loop the thread also finish all jobs and become disposed