仿真在线

专攻CAE仿真技术:Fluent,Ansys,Abaqus,Autoform,iSight,CFX,Nastran,HFSS,Maxwell

深入研究CAE仿真技术,10年如1日 研究范围:Fluent,Ansys,Abaqus,Autoform,iSight,CFX,Nastran,HFSS,Maxwell,Hypermesh有限元分析,提供有限元代做,有限元咨询

博客园 首页 新随笔 联系 订阅 管理

我在c#中调用C++的dll,内部使用了线程并detach使其独立于主线程UI运行。

但后来发现程序关闭后,任务列表中的进场依然存在,即app并未实际正常退出。

这个问题有很多人碰到和争论,但都没有给出明确的答案。

这里提供一个理论解释和绝佳的调试排除方法:

根本原因:程序退出之前,系统(或程序员自己,这个看开发工具)会调用Dll Unload Library,而调用这个实际上去调用dll的析构函数,这个函数一般是隐式的。这里系统会去调用各种基础设施的release。但如果是用户代码存在需要手动release的对象,系统是没办法的。而主线程关闭UI后,变成一直在这里等待系统资源释放。所以问题的根本原因是使用了某些必须手动释放,用户在推出dll工作线程时没有正确清理。

解决方法:首先终止线程,排除各种锁的等待,终止各种循环 while for等;寻找那个需要手动release的对象,包括各种内存和各种component对象,在主线程退出之前,显示调用dll内的方法清理掉。

 

调试排除方法(分段隔离法):

如果你的项目比较复杂,你在releaseApp方法中处理了一系列的对象释放。就是查不到问题在哪里,这时你可以使用return 0 分段作废(分段隔离)掉一些模块和代码过程,然后不断重复编译执行,直到找到问题不出现和出现的交界位置,这时你就找到了问题的所在了。

 

对于我碰到的具体问题是这样的,deteach的子线程顺利退出,但关闭后进程仍然不退出。一开始一直怀疑是deteach的问题,首先确认子线程正确退出, 在排除了mutex,thread等问题后,问题依旧。最后采用分段隔离法,找到了问题。原来是opencv的VideoCapture没有release,这是个组件的问题,由于并非使用new产生的,所以没有主动release导致了问题的产生。

 

如上分享,希望对其他开发者有用。

 

posted on 2023-11-08 11:24  CAE工作狂  阅读(75)  评论(0编辑  收藏  举报
专攻CAE仿真技术:Fluent,Ansys,Abaqus,Autoform,iSight,CFX,Nastran,HFSS,Maxwell,Hypermesh有限元分析,提供有限元代做,有限元咨询