0

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

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

}

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

我的期望/理解是字典的范围在同一个实例化的actor内,但是当下一个actor的实例出现时,我意识到_myDictionary有添加到另一个actor中的节点!所以,它给人的印象是字典在所有相同actor类型的实时实例之间共享!这是正确的理解还是再次调用了同一个已经实例化的actor?!

由于参与者实现了IRemindable我希望 GC 在取消注册后将参与者从集群中删除,但它似乎没有发生。静态字典是否有可能导致演员的实例一直存在?

4

2 回答 2

1

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

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


文档

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

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

保存 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");
  }
} 

文档更详细地解释了它。

于 2018-12-20T09:56:29.187 回答
1

我认为这更像是一个.Net问题,而不是Service Fabric问题。据我记得,静态实例仅在收集AppDomain后才会收集(通常在进程终止时)。

查看垃圾收集的基础知识,了解收集实例的方式和时间。

关于如何维护状态,我建议你看一下Service Fabric Reliable Actors 简介,它可能会帮助你实现你想要的。

更新

另外,看看Reliable Actors state management

希望能帮助到你!

于 2018-12-20T06:37:02.593 回答