Service Fabric参与者中的静态对象



有一个具有以下定义的服务结构参与者,通过实现IRemindable接口进行注册和注销。这个演员也有一本静态字典。

[StatePersistence(StatePersistence.None)]
[ActorService(Name = "ProcessorActorService")]
public class ProcessorActor : BaseActor, IRemindable
{
private static Dictionary<object,object> _myDictionary;
}

我的理解是,如果每个参与者的guid在实例化时不同,那么服务结构会创建同一参与者的多个实例。当创建每个参与者实例时,提醒的操作会将一个对象添加到字典中,以便稍后处理

我的期望/理解是,字典的作用域在同一个实例化的actor中,但当下一个actor的实例出现时,我意识到_myDictionary具有在另一个actoer中添加的节点!因此,它给人的印象是,字典是在同一演员类型的所有活动实例之间共享的!这是一个正确的理解,还是再次调用同一个已经实例化的参与者?!

由于actor实现了IRemindable,我希望GC在注销该actor之后将其从集群中删除,但这似乎并没有发生。静态字典是否可能导致参与者的实例保留?

我认为这更像是一个。网络问题,而不是服务结构的问题。据我记忆所及,静态实例只有在AppDomain被收集后才会被收集(通常是在进程终止时(。

看看垃圾收集的基础知识,了解如何以及何时收集实例。

关于如何维护状态,我建议您查看服务结构可靠参与者简介,它可能会帮助您实现您想要的目标。

更新

此外,还可以看看Reliable Actors的状态管理。

希望它能有所帮助!

我的理解是,如果每个参与者的guid在实例化时不同,那么服务结构会创建同一参与者的多个实例。

这是正确的。每个新ID都会生成Actor的一个新实例。


来自文档:

使用static修饰符声明静态成员,该成员属于类型本身,而不是特定对象。

当您将privatestaticDictionary<object,object> _myDictionary;声明为static时,您是在告诉CLR字段不属于该对象的实例,而是属于类型定义,在这种情况下,它会生成一个属于Actor类型的实例,而不是运行时创建和销毁的对象。

保存actor状态的正确方法是使用状态管理器,如下所示:

[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
public MyActor(ActorService actorService, ActorId actorId)
: base(actorService, actorId)
{
}
public Task<int> GetCountAsync()
{
return this.StateManager.GetStateAsync<int>("MyState");
}
} 

文档对此进行了更详细的解释。

最新更新