无法从非托管客户端释放.net服务组件对象(com+)的内存

本文关键字:对象 组件 服务组 com+ 内存 服务 net 释放 客户端 | 更新日期: 2023-09-27 17:58:15

我已经将c#dll公开为.net服务组件(com+)。它正被一个未授权的客户端(Unify Vision)使用。我已经在组件服务下部署了这个组件。

我将池大小设置为5,创建时间设置为2分钟。我正在服务器模式下运行com+。并将怠速停机时间设置为3分钟。

一切都很好,但一旦达到最大池大小(5),进程就会保持活力而不会被清理。正因为如此,如果我试图再创造一个物体,它就会失败并挂起。

消费者似乎没有释放物品。此服务组件公开了两种方法_Destory和Dispose。一旦物体被使用,我必须使用哪一个来释放它。此外,在调用这些方法之后,对象会立即被释放吗。有没有办法找出这个对象有多少引用?

另外,我需要使用JIT和设置自动完成属性之类的东西吗?。不过我已经试过了。

我不确定这个物体是否会被放回游泳池。如何跟踪?

请帮助

谢谢sveerap

无法从非托管客户端释放.net服务组件对象(com+)的内存

有两种方法_Destory和处理此服务暴露的组成部分一旦物体被使用,我必须使用哪一个来释放它。

由于您处理的是服务器(进程外)应用程序,客户端不应该调用Dispose()。如果您的组件配置正确,dispose将实际创建/激活一个新实例,只是为了调用dispose方法。请阅读文章《理解.NET中的企业服务(COM+)》中关于对象生命周期的内容,以了解全貌。

这个物体会被释放吗在呼叫这些方法。

是的,它会被送回游泳池。

有没有办法知道有多少对象有引用吗?

使用COM+资源管理器查看应用程序中的所有组件。将视图设置为status,您将看到对象数、激活对象数、池对象数和调用时间。

还有,我需要使用类似的东西吗JIT和设置自动完成属性我已经试过了选项。

是的,您必须使用JIT并调用ContextUtil.DeactivateOnReturn = true;

我不确定这个物体是否被释放回游泳池。怎样追踪这个?

您可以覆盖Activate和Deactivate方法,以查看组件何时从池中删除并释放回池。

下面是一个例子,它有一个最大对象数为1的池,但在方法调用后立即将实例返回到池:

using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
    [ComVisible(true)]
    [EventTrackingEnabled(true)]
    [JustInTimeActivation(true)]
    [ObjectPooling(CreationTimeout=60000, 
                   Enabled=true, MaxPoolSize=1, MinPoolSize=0)]
    public class Class1 : ServicedComponent
    {
        public Class1()
        {
        }
        public string Hello()
        {
            System.Diagnostics.Trace.TraceInformation("Call Hello");
            // We are done after this call so return this instance to the pool
            ContextUtil.DeactivateOnReturn = true;
            return "world";
        }
        // Get an instance from the pool
        protected override void Activate()
        {
            System.Diagnostics.Trace.TraceInformation("Activated");
            base.Activate();
        }
        // Return an instance to the pool
        protected override void Deactivate()
        {
            System.Diagnostics.Trace.TraceInformation("Deactivate");
            base.Deactivate();
        }
        // Runtime will call Dispose after method call (with disposing = true)
        protected override void Dispose(bool disposing)
        {
            System.Diagnostics.Trace.TraceInformation("Disposing = " + disposing);
            base.Dispose(disposing);
        }
    }
}

如果多个客户端同时调用Hello方法而不释放客户端对象,则会发现该方法不会阻塞(除了调用的持续时间),因为Hello方法返回后对象会被释放回池。使用DebugView查看调用的顺序。这里有两个客户端在呼叫Hello后立即进行睡眠同时呼叫。

00000001    0.00036997  [6068] Activated    
00000003    0.00160919  [6068] Call Hello   
00000005    0.00493093  [6068] Deactivate   
00000007    0.00567035  [6068] Disposing = True     
00000009    0.14866389  [6068] Activated    
00000011    0.14876986  [6068] Call Hello   
00000013    0.14885986  [6068] Deactivate   
00000015    0.14896829  [6068] Disposing = True