"安全手柄已经关闭"用的SerialPort和C#线程

编程入门 行业动态 更新时间:2024-10-25 13:17:41
本文介绍了"安全手柄已经关闭"用的SerialPort和C#线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

,大家下午好!

我有这个线程的SerialPort 包装,从串口在一条线上读取。这是我的线程的代码

I have this threaded SerialPort wrapper that reads in a line from the serial port. Here is my thread's code.

protected void ReadData() { SerialPort serialPort = null; try { serialPort = SetupSerialPort(_serialPortSettings); serialPort.Open(); string data; while (serialPort.IsOpen) { try { data = serialPort.ReadLine(); if (data.Length > 0) ReceivedData(serialPort, new ReceivedDataEventArgs(data)); } catch (TimeoutException) { // No action } } } catch (ThreadAbortException) { if (serialPort != null) serialPort.Close(); } }

当我打电话 MyThread的。中止(); 我得到一个异常(不带线或引用代码)安全处理已经关闭。任何人都可以发现什么,我做错了什么?谢谢你。

when I call myThread.Abort(); I get an exception (with no line or reference to code) "Safe handle has been closed". Can anyone spot what I am doing wrong? Thanks.

顺便说一句,我有一个开始()和停止( )创建线程并中止线程,恭恭敬敬。

By the way, I have a Start() and a Stop() that creates the thread and aborts the thread, respectfully.

推荐答案

我会怀疑,这是因为你使用Thread.Abort的结束线程 - 这通常是令人难以接受的。该线程的行为,当你的中止的它是不可预测的。正因为如此,既然串口是包装过的本地代码,也有本地的资源 - 通过在SafeHandle的代表.NET - 这出人意料地得到处置的,所以你得到的异常。

I would suspect that it is because you are using Thread.Abort to end the thread - which is generally frowned upon. The thread behavior when you abort it is not predictable. Because of that, since the serial port is a wrapper over native code, there are native resources - represented by a SafeHandle in .NET - which get disposed of unexpectedly and so you get the Exception.

您可以想想你的线程是这样发生的:

You can think about what happens with your thread like this:

  • 您启动你的线程
  • 您打开串口(分配本土资源和使用的SafeHandle(S)举行对这些资源)
  • 您启动从串口读
  • 然后在某个点(不期而至您的线程)调用Thread.Abort的就可以了
  • 极有可能在你的代码线程是在这一点上试图访问串行端口(读取数据)
  • 的线程被打死,串口句柄隐含地摧毁
  • 你从串行端口的ReadLine()函数中的代码抛出一个异常,因为它有句柄不再有效
  • you start your thread
  • you open the serial port (which allocates native resources and uses SafeHandle(s) to hold on to those resources)
  • you start reading from the serial port
  • then at some point (unexpected to your thread) you call Thread.Abort on it
  • most likely the code in your thread is at that point trying to access the serial port (to read data)
  • the thread gets killed and the serial port handle is destroyed implicitly
  • you get an exception thrown from the code inside the ReadLine() function of the serial port because the handle it had is no longer valid

你真的应该使用中止线程,让你得到一个合适的机会接近和串行端口的配置不同的方法。

You really should use a different method for aborting the thread so that you get a proper chance to close and dispose of the serial port.

一个适当的方式来关闭线程可以使用的ManualResetEvent这样实现:

A proper way to close your thread could be implemented using a ManualResetEvent like this:

protected ManualResetEvent threadStop = new ManualResetEvent(false); protected void ReadData() { SerialPort serialPort = null; try { serialPort = SetupSerialPort(_serialPortSettings); serialPort.Open(); string data; while (serialPort.IsOpen) { try { data = serialPort.ReadLine(); if (data.Length > 0) ReceivedData(serialPort, new ReceivedDataEventArgs(data)); } catch (TimeoutException) { // No action } // WaitOne(0) tests whether the event was set and returns TRUE // if it was set and FALSE otherwise. // The 0 tells the manual reset event to only check if it was set // and return immediately, otherwise if the number is greater than // 0 it will wait for that many milliseconds for the event to be set // and only then return - effectively blocking your thread for that // period of time if (threadStop.WaitOne(0)) break; } } catch (Exception exc) { // you can do something here in case of an exception // but a ThreadAbortedException should't be thrown any more if you // stop using Thread.Abort and rely on the ManualResetEvent instead } finally { if (serialPort != null) serialPort.Close(); } } protected void Stop() { // Set the manual reset event to a "signaled" state --> will cause the // WaitOne function to return TRUE threadStop.Set(); }

当然,使用事件的方法来阻止你有线程的要小心包括你所有的长时间运行的循环或任务的。如果你没有你的线程可能会出现不回应你的设置事件 - 直到它得到了长时间运行的循环,或者任务,并得到一个机会,以看到该事件已设置

Of course, when using the events method to stop the thread you have to be careful to include an event state check in all your long running loops or tasks. If you don't your thread may appear not to respond to your setting the event - until it gets out of the long-running loop, or task and gets a chance to "see" that the event has been set.

更多推荐

"安全手柄已经关闭"用的SerialPort和C#线程

本文发布于:2023-05-25 10:53:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/226591.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:手柄   线程   amp   QUOT   SerialPort

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!