Service Fabric 参与者中的静态对象
Static objects in Service Fabric actors
有一个具有以下定义的服务结构参与者,它通过实现 IRemindable
接口进行注册和注销。这个演员也有静态字典。
[StatePersistence(StatePersistence.None)]
[ActorService(Name = "ProcessorActorService")]
public class ProcessorActor : BaseActor, IRemindable
{
private static Dictionary<object,object> _myDictionary;
}
我的理解是,如果每个 actor 的 guid 在实例化时不同,则服务结构会创建同一 actor 的多个实例。当创建每个 actor 实例时,提醒的操作将一个对象添加到字典中以供稍后处理。
我的 expectation/understanding 字典的范围在同一个实例化的 actor 中,但是当下一个 actor 的实例出现时,我意识到 _myDictionary
有添加的节点在另一个演员!所以,它给人的印象是字典在同一演员类型的所有活动实例之间共享!是理解正确还是再次调用同一个已经实例化的actor?!
由于 actor 实现了 IRemindable
我希望 GC 在取消注册后将 actor 从集群中删除,但它似乎没有发生。静态字典是否可能导致演员的实例停留?
我认为这更像是 .Net 问题,而不是 Service Fabric 问题。据我所知,只有在 AppDomain 被收集后才会收集静态实例(通常在进程终止时)。
查看 Fundamentals of Garbage Collection 收集实例的方式和时间。
关于如何保持状态,建议你看一下Introduction to Service Fabric Reliable Actors,它可能会帮助你实现你想要的。
更新
另外,看看Reliable Actors state management。
希望对您有所帮助!
My understanding is that service fabric creates multiple instances of the same actor if each actor's guid is different at instantiation time.
这是正确的。每个新 ID 都会生成一个新的 Actor 实例。
来自docs:
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.
当您将 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");
}
}
documentation 解释得更详细。
有一个具有以下定义的服务结构参与者,它通过实现 IRemindable
接口进行注册和注销。这个演员也有静态字典。
[StatePersistence(StatePersistence.None)]
[ActorService(Name = "ProcessorActorService")]
public class ProcessorActor : BaseActor, IRemindable
{
private static Dictionary<object,object> _myDictionary;
}
我的理解是,如果每个 actor 的 guid 在实例化时不同,则服务结构会创建同一 actor 的多个实例。当创建每个 actor 实例时,提醒的操作将一个对象添加到字典中以供稍后处理。
我的 expectation/understanding 字典的范围在同一个实例化的 actor 中,但是当下一个 actor 的实例出现时,我意识到 _myDictionary
有添加的节点在另一个演员!所以,它给人的印象是字典在同一演员类型的所有活动实例之间共享!是理解正确还是再次调用同一个已经实例化的actor?!
由于 actor 实现了 IRemindable
我希望 GC 在取消注册后将 actor 从集群中删除,但它似乎没有发生。静态字典是否可能导致演员的实例停留?
我认为这更像是 .Net 问题,而不是 Service Fabric 问题。据我所知,只有在 AppDomain 被收集后才会收集静态实例(通常在进程终止时)。
查看 Fundamentals of Garbage Collection 收集实例的方式和时间。
关于如何保持状态,建议你看一下Introduction to Service Fabric Reliable Actors,它可能会帮助你实现你想要的。
更新
另外,看看Reliable Actors state management。
希望对您有所帮助!
My understanding is that service fabric creates multiple instances of the same actor if each actor's guid is different at instantiation time.
这是正确的。每个新 ID 都会生成一个新的 Actor 实例。
来自docs:
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.
当您将 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");
}
}
documentation 解释得更详细。