Safe handle has been closed异常的原因及解决思路

简介: Exception: 2013-05-30 19:28:26,750 [3] ERROR Topshelf.Runtime.Windows.WindowsServiceHost Error 0- The service threw an unhandled exception System.

Exception:

2013-05-30 19:28:26,750 [3] ERROR Topshelf.Runtime.Windows.WindowsServiceHost Error 0- The service threw an unhandled exception
System.ObjectDisposedException: Safe handle has been closed
   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   at Microsoft.Win32.Win32Native.SetEvent(SafeWaitHandle handle)
   at System.Threading.EventWaitHandle.Set()
   at System.IO.Ports.SerialStream.AsyncFSCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

异常原因及解决思路:
一:
The message says that you are trying to access an object which is already disposed.

Check and see your objects are handling well the 'Dispose' and 'Class Destruction'
PokeIn disposes client's objects when the client is disconnected. But this operation is Thread and Exception safe.
http://pokein.com/Discussions/tabid/62/forumid/4/postid/1069/scope/posts/Default.aspx

二:
You are disposing something which is still being used by a different thread.
http://stackoverflow.com/questions/4473216/diagnose-objectdisposedexception-safe-handle-has-been-closed
三:

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:

  • 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.

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.

What would be the proper way to close my thread. The Stop()/Start() are used for when I reconfigure the port.

There are a few ways you could do it and I've given an example using a ManualResetEvent which is a pretty common mechanism..

You're welcome.. I hope you understand why Thread.Abort is not good practice. If you would like to find out more on the subject - there is a really great book about concurrency in Windows by Joe Duffy: bluebytesoftware.com/books/winconc/winconc_book_resources.html

I've found that unplugging USB-based serial ports when they're open tends to cause weird behaviors including "safe handle has been closed" exceptions. For devices which are supposed to operate as long as they're plugged in, but which may be unplugged at any time, the only remedy I've found to work consistently is to spawn a separate application to handle each device, and use some sort of pipe to bind such applications to the main app. Really horribly hokey, but I don't know what else to do.

http://stackoverflow.com/questions/1319003/safe-handle-has-been-closed-with-serialport-and-a-thread-in-c-sharp

相关文章
|
存储 JavaScript 前端开发
|
9月前
|
机器学习/深度学习 存储 编解码
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
430 7
YOLOv11改进策略【Neck】| ArXiv 2023,基于U - Net v2中的的高效特征融合模块:SDI(Semantics and Detail Infusion)
|
8月前
|
存储 人工智能 搜索推荐
炸裂!!!Deepseek接入个人知识库,回答速度飞起来,确实可以封神了
高效管理知识、快速获取信息成为提升工作效率的关键。无论是做技术的同学还是普通的上班族,在日常积累了大量的知识数据和内容。项目文档、会议记录到技术手册、业务流程,这些信息如同宝藏一般,等待着被高效利用。然而,面对海量的数据,如何快速准确地获取到自己想要的内容,成为了提升工作效率的关键挑战。这时,一个高效的知识库就显得尤为重要。今天,就给大家详细介绍如何利用DeepSeek和Cherry-Studio,搭建属于自己的高效专属知识库,让你在信息的海洋中如鱼得水。
489 1
|
机器学习/深度学习 存储 传感器
足球黑科技之AI与足球智能分析
最近的足球盛宴引发了球迷的狂欢,阿根廷对沙特的越位,日本对西班牙的出界球,葡萄牙对乌拉圭C罗是否碰到了球等热点事件是否引发了你的关注呢。其实在这些热点背后,离不开足球智能裁判的辅助,足球作为全世界最受欢迎的运动,也一直致力于和高科技的结合。此篇文章,给大家带来了足球视频智能分析,让我们一起看看AI是如何在足球运动中大放光彩的的吧!
1796 3
足球黑科技之AI与足球智能分析
|
9月前
|
机器学习/深度学习 数据可视化 算法
YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进
YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进
1605 6
YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进
|
设计模式 测试技术
依赖注入与工厂设计模式的区别
【8月更文挑战第22天】
270 0
|
数据安全/隐私保护 计算机视觉 开发者
OpenCV中使用NumPy模块操作像素讲解及实战(附源码 超详细)
OpenCV中使用NumPy模块操作像素讲解及实战(附源码 超详细)
373 0
OpenCV中使用NumPy模块操作像素讲解及实战(附源码 超详细)
|
关系型数据库 MySQL 数据处理
一文彻底理解乐观锁与悲观锁
一文彻底理解乐观锁与悲观锁
1357 0