ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 当创建它的线程终止时,CLR是否释放了COM对象?

2019-05-29 07:53:29  阅读:241  来源: 互联网

标签:c net vb-net com com-interop


我一直无法弄清楚如何搜索这种怀疑的确认,但我看到证据表明在一个线程上创建的COM对象不再可用于其他线程(已经与其底层RCW分离的COM对象无法使用)一旦代码在创建它的线程上停止执行(并且该线程可能已终止).这是一个非常隐蔽的问题,因为我在整个代码中都调用了System.Runtime.InteropServices.Marshal.ReleaseComObject,但是我无法识别它们中的任何一个被调用导致此错误.最后我得出结论,当辅助线程停止执行时,COM对象显然被隐式释放.这可能是真的吗?这是记录在案的行为?

解决方法:

是的,COM对象往往具有强大的线程亲和力.线程不是COM中的次要实现细节.与.NET不同,COM为COM类提供了线程安全保证. COM可以发布它支持的线程类型,“公寓”(即“非线程安全”)是一种非常常见的选择. COM确保满足这些要求,而无需程序必须提供任何帮助.从一个线程到另一个线程的调用,以便始终以线程安全的方式使用该对象是自动的.在.NET代码中,您通常必须自己使用Control.BeginInvoke或Dispatcher.BeginInvoke这样做.

这样做的一个自动结果是拥有一个或多个允许退出的COM对象的线程将自动释放这些对象.这是必要的,因为不再有办法满足线程安全要求.在这之后试图使用它们会炸弹.除了确保线程保持足够长的时间以保持对这些对象的维护之外,没有办法解决这个问题.类似地,您需要保持UI线程的活动时间足够长,以确保Dispatcher.BeginInvoke仍然可以在.NET中工作.

Fwiw,是的,使用Marshal.ReleaseComObject()可以给你很多关于这一点.显式内存管理具有生成错误程序的悠久历史,并且自动垃圾收集提供了治愈. GC非常有能力在没有你帮助的情况下发布COM对象,并且永远不会出错.它只需要更长的时间来解决它.如果您知道COM对象具有异常高的资源使用率,并且需要确定性地释放它,那么您执行与为昂贵的.NET对象图执行完全相同的操作:GC.Collect()有助于此.检查this answer是否有不必要地使用Marshal.ReleaseComObject()的原因.

标签:c,net,vb-net,com,com-interop
来源: https://codeday.me/bug/20190529/1176485.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有