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

标签 wcf com garbage-collection access-violation clarion

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

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

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

我的猜测是启动 COM 会以某种方式被重用或回收。我不想这样!我能确保它永远死去吗?或者,如果不可能,我可以将其标记为不进行垃圾回收吗?显然,GC.KeepAlive 在这里无关紧要,因为它们是不同方法中的不同线程。

更多详细信息:COM 对象最近支持 MTA。它们是线程安全且完全并发的,但之前,当它们只是 STA 时,不存在这样的问题。此外,当这些家伙在单独的线程中运行时,在 WCF 之外不会发生任何不良情况。

最佳答案

好的。看起来我正在做这件事。

它是该死的隐藏单例对象,或者更确切地说,是编写 COM 的平台的运行时库(SoftVelocity Clarion)。当启动 COM 被杀死时,由于某种原因它被释放,可能是因为引用计数下降并且是时候卸载 DLL 本身了。虽然当我调整 DllCanUnloadNow 时,它没有帮助,但我会弄清楚它来自哪里。

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

此外,不要忘记在 .Destruct 方法中调用 AttachThreadToClarion(TRUE),因为垃圾收集线程会有所不同。

此问题可能会在广泛使用运行时或全局对象的老一代 IDE 中出现。谨防。

关于wcf - 垃圾回收后 WCF 中 COM 对象的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23417969/

相关文章:

java - 在 Eclipse 中查看 gcmv 使用的堆数量?

wcf - Odata 压缩 - 有任何支持吗? (适用于 WinRT 的 WCF 数据服务 5.0)

c# - SQL Server 项目的进程间通信

.net - 如何找到 COM prog id?

c# - Silverlight低级套接字支持?

Java 不释放带有 finalize() 覆盖的对象

wcf - ApplyClientBehavior 没有被调用

.net - MVVM客户端中的WCF契约(Contract)和模型

python - Excel python COM 对象的文档?

javascript - 在 javascript 中可以防止失效的监听器吗?