Question

The computer is connected to measuring device via a physical COM1. I have simple form where I open a serial port, tell the device that I'm alive and occasionally the device sends data. (every some minutes)

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");

The read function (which works):

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

After approximately one minute the application crashes (even while debugging). It reports an ObjectDisposedException (for the underlying stream?). The message tells that the SafeHandle was closed. Stack strace is below:

at Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait) at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()*

Any ideas? The problem is reported widely but usually involve the device beeing physically detached from the PC.

Was it helpful?

Solution 2

It seemed like the RS232 cable (adapter) caused the crashes of the underlying serial port stream. Switched to an FTDI cable, that worked.

A look into the .NET Framework source code helped a lot. But I think the thrown ObjectDisposedException should be caught by the SerialPort, not by the user.

OTHER TIPS

Try checking IsOpen before reading.

Also, is there any chance the object containing _serialPort has been dereferenced and garbage collected? If you're never accessing _serialPort from another thread, try making it a private variable in Read().

ObjectDisposedException means someone called Dispose on the object. What are you doing after you start the read thread? Do you wait for the read thread to complete before you exit the program? Otherwise, maybe the read thread is still running with the program exits.

I had something similiar happen to me about a year ago. For some reason, some characters at the end of the read buffer would cause the C# interface to the serial port to close itself. It usually happened when \r\n was at the end of the buffer, although it could have been some other characters, too.

Ended up just buying a license to a commercial serial port DLL.

Good luck!

You have _serialPort declared as local SerialPort in the thread-starting code, so what is _serialPort referring to in Read() ?

Try creating the _serialPort object in the Read() method to be sure it's in the context of the same thread.

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top