垃圾回收后WCF中COM对象的访问冲突

垃圾回收后WCF中COM对象的访问冲突,wcf,com,garbage-collection,access-violation,clarion,Wcf,Com,Garbage Collection,Access Violation,Clarion,我有一个自托管的WCF应用程序,其中服务对象(每次调用、单个并发)使用嵌入式COM对象(在整个调用过程中从类中引用)构建在一个名为Clarion的平台上。COM实例与服务对象一起创建和销毁。但是,在下面,他们访问一个需要很长时间初始化的单例存储库(非常类似于此:)。所以第一个电话很长。因此,我必须在启动时调用它 如果我在启动时没有实例化COM对象,那么一切都很好(除了长时间的第一次调用)。但如果我这样做,在垃圾收集之后,下一个请求将在尝试访问COM时崩溃,并出现访问冲突异常 服务对象实现了IDi

我有一个自托管的WCF应用程序,其中服务对象(每次调用、单个并发)使用嵌入式COM对象(在整个调用过程中从类中引用)构建在一个名为Clarion的平台上。COM实例与服务对象一起创建和销毁。但是,在下面,他们访问一个需要很长时间初始化的单例存储库(非常类似于此:)。所以第一个电话很长。因此,我必须在启动时调用它

如果我在启动时没有实例化COM对象,那么一切都很好(除了长时间的第一次调用)。但如果我这样做,在垃圾收集之后,下一个请求将在尝试访问COM时崩溃,并出现访问冲突异常

服务对象实现了
IDisposable
,其中使用
Marshal.ReleaseComObject
可以很好地释放所有COM对象。 启动调用还释放COM对象

我的猜测是,初创公司的COM以某种方式得到了重用或回收。我不想这样!我能保证它永远死去吗?或者如果不可能,我可以将其标记为不用于垃圾收集吗?显然,
GC.KeepAlive
在这里是不相关的,因为它们是不同方法中的不同线程


更多详细信息:COM对象最近已具备MTA功能。它们是线程安全且完全并发的,但以前,当它们仅是STA时,不存在这样的问题。而且,当这些家伙在单独的线程中运行时,在WCF之外没有什么不好的事情发生

好的。看来我在上面

它是血腥隐藏的单例对象,或者更确切地说,是编写COM的平台(SoftVelocity Clarion)的运行库。当启动COM被终止时,由于某种原因,它被解除分配,可能是因为引用计数下降,是时候卸载DLL本身了。虽然我调整了
DllCanUnloadNow
,但没有帮助,但我会找出它的来源

编辑:Clarion对COM对象的支持并不简单。由模板生成的代码执行数据库字典(
DctInit
DctKill
分别)和主程序中某些特定类的分配和解除分配,这些类在主线程结束时结束。然而,在MTA COM对象中,主线程的结束并不意味着程序的结束。因此,最简单的解决方案是嵌入代码以防止执行
DctKill

另外,不要忘记在.Destruct方法中调用
AttachThreadToClarion(TRUE)
,因为垃圾收集线程是不同的


在广泛使用运行时或全局对象的旧一代IDE中,可能会出现此问题。当心

请不要显式调用
封送。ReleaseComObject
来尝试。好的,这很有趣。一旦我删除了对Marshal.ReleaseComObject的调用,它就彻底崩溃了!甚至不用等待垃圾收集。也许有某种可重用性池。我可以清除或清除COM对象吗?没有可重用的COM对象池。您可以使用
GCHandle.Alloc
防止COM对象被GC'ed,但是,这是错误的。我认为这个问题是由以下内容引起的:“COM对象最近被赋予了MTA功能……当它们仅为STA时,就不存在这样的问题。”。这些对象是在
ThreadingModel=“Free”
ThreadingModel=“两者”
中注册的吗?您确定他们没有在内部使用任何其他或第三方COM对象(可能仍然是STA)吗?谢谢。请详细说明GCHandle.Alloc(作为一个极端解决方案)。是的,当然这个问题是由他们转换成MTA引起的。是的,它们是用ThreadingModel=Both注册的,并且在WCF之外都可以正常工作。