Service Fabric参与者中的静态对象

时间:2018-12-20 02:59:21

标签: c# azure azure-service-fabric service-fabric-actor

有一个具有以下定义的服务结构参与者,通过实现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在注销集群后将其从集群中删除,但似乎没有发生。静态字典是否可能导致参与者的实例卡住?

2 个答案:

答案 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对其进行了详细说明。