打开的串行端口使 C# 应用程序崩溃

发布于 2024-07-17 10:07:13 字数 1181 浏览 6 评论 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();
}

大约一分钟后,应用程序崩溃(即使在调试时)。 它报告一个 ObjectDisposeException(对于底层流?)。 该消息表明 SafeHandle 已关闭。 堆栈跟踪如下:

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

沫尐诺 2024-07-24 10:07:13

在阅读之前尝试检查 IsOpen。

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

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().

忆梦 2024-07-24 10:07:13

看来RS232电缆(适配器)导致了底层串行端口流的崩溃。 改用 FTDI 电缆,效果很好。

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

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.

难如初 2024-07-24 10:07:13

ObjectDisposeException 意味着有人对该对象调用了 Dispose。 启动阅读线程后你在做什么? 在退出程序之前是否等待读取线程完成? 否则,可能读取线程仍在运行,程序已退出。

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.

夏花。依旧 2024-07-24 10:07:13

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

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

祝你好运!

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!

鸩远一方 2024-07-24 10:07:13

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

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

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.

八巷 2024-07-24 10:07:13

1)
线程_readThread = 新线程(读取);

// 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文