我在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导致了问题的产生。
如上分享,希望对其他开发者有用。
标签:调用,C#,C++,dll,问题,退出,线程,release From: https://www.cnblogs.com/johnsen/p/17817002.html