有一个具有以下定义的服务结构参与者,通过实现IRemindable
接口可以注册然后取消注册。这个演员也有静态字典。
[StatePersistence(StatePersistence.None)]
[ActorService(Name = "ProcessorActorService")]
public class ProcessorActor : BaseActor, IRemindable
{
private static Dictionary<object,object> _myDictionary;
}
我的理解是,如果每个参与者的GUID在实例化时都不同,那么服务结构将创建同一参与者的多个实例。在创建每个actor实例时,提醒动作将一个对象添加到字典中以供以后处理。
我的期望/理解是,字典的作用域在同一个实例化actor内,但是当下一个actor的实例出现时,我意识到_myDictionary
具有在另一个actor中添加的节点!因此,给人的印象是该词典在同一参与者类型的所有活动实例之间共享!是再次呼唤正确的认识还是已经被实例化的演员?
由于actor实现了IRemindable
,因此我希望GC在注销集群后将其从集群中删除,但似乎没有发生。静态字典是否可能导致参与者的实例卡住?
答案 0 :(得分:1)
我认为这更多是 .Net 问题,而不是 Service Fabric 问题。据我所知,只有在收集 AppDomain 后(通常在进程终止时),才会收集静态实例。
看看Fundamentals of Garbage Collection有关如何以及何时收集实例的信息。
关于如何维护状态,建议您看看Introduction to Service Fabric Reliable Actors,它可能有助于您实现所需的目标。
更新
还要看一下Reliable Actors state management。
希望有帮助!
答案 1 :(得分:1)
我的理解是,如果每个参与者的GUID在实例化时都不同,那么服务结构将创建同一参与者的多个实例。
这是正确的。每个新的ID都会生成Actor的新实例。
来自docs:
使用static修饰符声明一个静态成员,该成员属于类型本身而不是特定对象。
当您将private
static
Dictionary<object,object> _myDictionary;
声明为静态时,您是在告知 CLR < / em> ,该字段不属于该对象的实例,而是属于类型定义,在这种情况下,它将生成一个属于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");
}
}
documentation对其进行了详细说明。