首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >COM-object是无意中释放的。

COM-object是无意中释放的。
EN

Stack Overflow用户
提问于 2016-03-04 14:54:57
回答 1查看 105关注 0票数 0

我有一个用于单元测试的帮助类,它共享内存中COM对象的引用:

代码语言:javascript
复制
public class UnitTestGeometryProvider 
{
    public static readonly IGeometry Geometry = Deserialize();
}

几何是从Xml文件反序列化的,Xml文件作为资源文件存储并附加到项目中。之后,它被包装到一个COM对象中:

代码语言:javascript
复制
public static IGeometry Deserialize() 
{
    return (IGeometry) new XMLSerializerClass().LoadFromString(myXDoc.OuterXml, null, null);
}

现在我有了两个测试方法,它们使用这个类中存储的几何图形:

代码语言:javascript
复制
[TestClass()]
public class MyTest
{
    [TestMethod()]
    public void FirstTest()
    {
        var p = UnitTestGeometryProvider.Geometry;
    }   

    [TestMethod()]
    public void SecondTest()
    {
        var p = UnitTestGeometryProvider.Geometry;
    }
}

当运行第二个程序时,我得到一个COMException:

无法使用已与其基础RCW分离的COM对象。

我想知道为什么对COM对象的引用是在UnitTestGeometryProvider中标记为UnitTestGeometryProvider时释放的,而且我也没有显式地释放它。因此,即使实例的托管资源超出了作用域(它不是静态的),底层COM对象也只能在我的所有测试完成时才会消失,或者在应用程序结束时更一般,或者我是否遗漏了任何东西?

我正在使用ArcObjects和Visual。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-19 08:35:28

由于汉斯·帕桑的评论,我发现了实际的问题。

显然,Visual Framework决定为每个测试创建一个单独的线程。因此,每当我创建一个COM对象时--不管它是静态的还是非静态的--这个对象都存在于这个单线程上,不能在另一个线程中使用。如果线程死掉了,也会执行COM对象,或者更精确地说,引用它。这导致GC抛出COM对象,因为在线程中不再存在对COM对象的托管引用。

解决方案非常严格:我将静态字段更改为实例成员,并在我的测试类中创建了一个UnitTestGeometryProvider类型的实例成员。因此,每个测试都生成一个新的提供程序。

但是,这个解决方案非常恼人,因为必须初始化Geometry-property,因此Deserialize-method只对每个测试运行,而不是对所有测试只运行一次。

我不知道是否有一个线程安全的解决方案,以避免在第一个使COM对象失效的线程终止对COM对象的引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35799042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档