我已将c#dll暴露为.net服务组件(com +)。它由一个无人管理的客户(Unify Vision)消费。我已在组件服务下部署了此组件。
我将池大小设置为5,将创建时间设置为2分钟。我在服务器模式下运行com +。并将空闲关机时间设置为3分钟。
一切正常,但一旦达到最大池大小(5),进程就会保持活跃状态而不会被清理干净。由于这个原因,如果我试图创造一个更多的对象,它的失败和悬挂。
似乎对象没有被消费者释放。此服务组件有两种方法_Destroy和Dispose。一旦使用它,我必须使用哪一个来释放它。此外,在调用这些方法后,对象是否会立即释放。有没有办法找出对象有多少引用?
另外,我是否需要使用JIT之类的东西并设置自动完成属性?我已经尝试过这个选项了。
我不确定对象是否会被释放回池中。如何追踪?
请帮忙
由于 sveerap
答案 0 :(得分:2)
有两种方法_Destroy和 处理由此服务暴露 零件。在使用对象后,我必须使用哪一个来释放它。
由于您正在处理服务器(进程外)应用程序,因此客户端不应该调用Dispose()。如果您的组件配置正确,则dispose将实际创建/激活一个新实例,以便调用Dispose方法。请阅读文章Object Lifetimes中的Understanding Enterprise Services (COM+) in .NET了解全貌。
对象是否会被释放 紧接着打电话给这些 方法
是的,它会被退回到游泳池。
有没有办法找出多少 引用是否存在于对象中?
使用COM + Explorer查看应用程序中的所有组件。将视图设置为状态,您将看到对象的数量,激活的对象的数量,池化对象的数量以及呼叫时间。
另外,我需要使用类似的东西吗? 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之后立即同时调用sleep。
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