0

计算机通过物理 COM1 连接到测量设备。我有一个简单的表格,我打开一个串口,告诉设备我还活着,偶尔设备会发送数据。(每隔几分钟)

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 已关闭。堆栈跟踪如下:

在 Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait) 在 System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System. System.Threading.ThreadHelper.ThreadStart() 处的 Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态)*

有任何想法吗?该问题被广泛报道,但通常涉及设备与 PC 物理分离。

4

6 回答 6

1

在阅读之前尝试检查 IsOpen。

此外,是否有可能包含 _serialPort 的对象已被取消引用并被垃圾收集?如果您从未从另一个线程访问 _serialPort,请尝试在 Read() 中将其设为私有变量。

于 2009-04-28T18:04:47.660 回答
1

似乎 RS232 电缆(适配器)导致了底层串行端口流的崩溃。切换到 FTDI 电缆,这工作。

查看 .NET Framework 源代码有很大帮助。但我认为抛出的 ObjectDisposedException 应该由 SerialPort 捕获,而不是由用户捕获。

于 2009-05-10T18:21:22.077 回答
0

ObjectDisposedException 表示有人在对象上调用了 Dispose。启动读线程后你在做什么?您是否在退出程序之前等待读取线程完成?否则,程序退出时,可能读取线程仍在运行。

于 2009-04-28T11:39:30.940 回答
0

大约一年前,我也发生过类似的事情。出于某种原因,读取缓冲区末尾的某些字符会导致串行端口的 C# 接口自行关闭。它通常发生在\r\n缓冲区的末尾,尽管它也可能是其他一些字符。

最后只是购买了商业串行端口 DLL 的许可证。

祝你好运!

于 2009-04-28T12:26:28.970 回答
0

您在线程启动代码中将 _serialPort 声明为本地 SerialPort ,那么 Read() 中的 _serialPort 指的是什么?

尝试在 Read() 方法中创建 _serialPort 对象,以确保它位于同一线程的上下文中。

于 2009-04-28T18:27:13.767 回答
0

1) 线程_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
于 2009-07-02T18:59:36.220 回答