我有一个用于单元测试的帮助类,它共享内存中COM对象的引用:
public class UnitTestGeometryProvider
{
public static readonly IGeometry Geometry = Deserialize();
}几何是从Xml文件反序列化的,Xml文件作为资源文件存储并附加到项目中。之后,它被包装到一个COM对象中:
public static IGeometry Deserialize()
{
return (IGeometry) new XMLSerializerClass().LoadFromString(myXDoc.OuterXml, null, null);
}现在我有了两个测试方法,它们使用这个类中存储的几何图形:
[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。
发布于 2016-05-19 08:35:28
由于汉斯·帕桑的评论,我发现了实际的问题。
显然,Visual Framework决定为每个测试创建一个单独的线程。因此,每当我创建一个COM对象时--不管它是静态的还是非静态的--这个对象都存在于这个单线程上,不能在另一个线程中使用。如果线程死掉了,也会执行COM对象,或者更精确地说,引用它。这导致GC抛出COM对象,因为在线程中不再存在对COM对象的托管引用。
解决方案非常严格:我将静态字段更改为实例成员,并在我的测试类中创建了一个UnitTestGeometryProvider类型的实例成员。因此,每个测试都生成一个新的提供程序。
但是,这个解决方案非常恼人,因为必须初始化Geometry-property,因此Deserialize-method只对每个测试运行,而不是对所有测试只运行一次。
我不知道是否有一个线程安全的解决方案,以避免在第一个使COM对象失效的线程终止对COM对象的引用。
https://stackoverflow.com/questions/35799042
复制相似问题