有一个具有以下定义的服务结构参与者,通过实现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修饰符声明静态成员,该成员属于类型本身,而不是特定对象。
当您将private
static
Dictionary<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");
}
}
文档对此进行了更详细的解释。