[英]COM-object was released unintendedly
我的单元测试有一个帮助程序类,该类共享对内存中COM对象的引用:
public class UnitTestGeometryProvider
{
public static readonly IGeometry Geometry = Deserialize();
}
从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
标记为static
,而我没有明确释放它。 所以,即使 托管资源的实例将走出去的范围(这是不它是静态的),下面的COM对象应该走在应用程序终止,只有当所有我的测试成品或更一般的,还是我错过有什么事吗
我正在使用ArcObjects和Visual NUnit。
由于Hans Passant的评论,我发现了实际的问题。
显然,Visual-NUnit-Framework决定为每个测试创建一个单独的线程。 因此,无论何时创建COM对象(无论是否为静态对象),该对象都位于该单个线程上,并且不能在另一个线程中使用。 如果线程死亡,也执行COM对象,或者更确切地说,引用该对象。 这导致GC开始抛出COM对象,因为该线程中不再存在对其的托管引用。
解决方案非常棘手:我将静态字段更改为实例成员,并在测试类中创建了UnitTestGeometryProvider
类型的实例成员。 因此,每次测试都会生成一个新的提供程序。
但是,此解决方案非常烦人,因为必须初始化Geometry
属性,并且因此对每个测试运行Deserialize
方法,而不是对所有测试仅运行一次。
我不知道是否有一个线程安全的解决方案来在初始化它的第一个线程死亡时不终止对COM对象的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.