场景:
C++部分封装为COM,C#来调用。调用可能是在线程中的。
应用程序退出时,C#的部分 自动清理,某些线程可能还没有完全停掉。
COM内部的东西也在释放内存。
这个时候,稍有不慎,就会崩溃。
冲突点:
1. 多个线程重复ReleaseComObject,
2. C#某个线程还在使用,另外一个线程或者主线程去ReleaseComObject。
3. 已经进行了ReleaseComObject, c#某个线程还在使用。
最让人郁闷的地方是:
try { Marshal.ReleaseComObject(obj); obj = null; } catch (System.ArgumentException ex) { Debug.Assert(false, ex.Message); }
这个Try-Catch 是没用的,出来异常,照样死掉。
仔细排查,解决办法如下:
1. 针对多个线程重复ReleaseComObject的问题,确定“谁创建谁Release”的原则,无法确定的,留到App Exit的时候Release。
2. 资源已经Release,还在使用的问题
检查发现有个线程sleep了100个毫秒,这个赶紧改掉。App exit的时候,100ms可以干好多事情的。
另外, 不知道有没有好的办法来判断COM对象存在与否,能否安全调用。
3. 正在使用的资源,另外一个线程去Release, 遵照第一个原则来执行。
4. 线程内循环的方法,粒度尽量小,便于及时更新UI和快速刹车。
5. 线程工厂,尽可能的简单明了。复杂的代价是写的痛苦,维护的痛苦。
尝试着改了几个地方,发现还是有问题。失控的多线程遇上了COM,真的难搞。