【发布时间】:2016-05-19 16:35:28
【问题描述】:
我的单元测试有一个辅助类,它共享对内存中 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,而我没有明确释放它。因此,即使 if 实例的 托管资源 会超出范围(这不是静态的),只有当我的所有应用程序终止时测试已完成或更一般,还是我错过了什么?
我正在使用 ArcObjects 和 Visual NUnit。
【问题讨论】:
-
用 COM 对象初始化 static 字段是一个非常糟糕的主意,而且只能在偶然情况下起作用。您无法保证这会在正确的时间和正确的线程上发生。 lot 很重要,单元线程 COM 对象由特定线程拥有,如果该线程结束,则该对象将像门钉一样死掉。改为使用属性,如果对象仍然为空,则调用 Deserialize()。
-
@HansPassant 好吧,但是这个测试不是在单线程测试之上给出的吗?这里没有涉及多线程,还是
static暗示了它自己? -
这样的变量从类型初始化器(又名静态构造器)获取它的值。 .NET 很少保证它们何时或如何运行,只保证它们运行得足够早。您有一个测试运行程序,它可能有自己的想法,它在运行测试之前如何初始化所有内容。如果您想要保证它永远不会出错,那么您就无法获得,那么您有非常有力的证据表明它确实出错了。
标签: c# static com arcobjects