在Service Fabric中,我试图调用ActorService并获取所有参与者的列表。我没有任何错误,但是没有演员返回。总是零。
这就是我添加演员的方式:
ActorProxy.Create<IUserActor>(
new ActorId(uniqueName),
"fabric:/ECommerce/UserActorService");
这就是我尝试获取所有演员列表的方法:
var proxy = ActorServiceProxy.Create(new Uri("fabric:/ECommerce/UserActorService"), 0);
ContinuationToken continuationToken = null;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
List<ActorInformation> activeActors = new List<ActorInformation>();
do
{
var proxy = GetUserActorServiceProxy();
PagedResult<ActorInformation> page = await proxy.GetActorsAsync(continuationToken, cancellationToken);
activeActors.AddRange(page.Items.Where(x => x.IsActive));
continuationToken = page.ContinuationToken;
}
while (continuationToken != null);
但是,无论我添加了多少用户,页面对象将始终具有零项。我想念什么?
答案 0 :(得分:1)
ActorServiceProxy.Create(Uri, int, string)中的第二个参数int
是分区键(您可以了解更多有关actor分区here的信息)。
这里的问题是您的代码仅检查一个分区(partitionKey = 0
)。
因此解决方案非常简单-您必须遍历服务的所有分区。这是一个带有代码示例的answer,用于获取分区并对其进行迭代。
我不是第一次发现这一点,但是之所以没有让任何演员返回,是因为您没有创建任何演员-您正在创建代理!
产生这种混乱的原因是Service Fabric角色是虚拟的,即从用户的角度来看,actor始终存在,但在现实生活中,Service Fabric会自动维持actor对象的生存期,并根据需要恢复其状态。
这里是documentation的引文:
演员会自动激活(导致要构造演员对象)第一次将消息发送到演员ID的消息。一段时间后,actor对象将被垃圾回收。将来,再次使用actor ID,将导致构造新的actor对象。当存储在状态管理器中时,参与者的状态会超过对象的生命周期。
在您的示例中,您从未向演员发送任何消息!
这是我在Program.cs
中新建的Actor项目编写的代码示例:
// Please don't forget to replace "fabric:/Application16/Actor1ActorService" with your actor service name.
ActorRuntime.RegisterActorAsync<Actor1> (
(context, actorType) =>
new ActorService(context, actorType)).GetAwaiter().GetResult();
var actor = ActorProxy.Create<IActor1>(
ActorId.CreateRandom(),
new Uri("fabric:/Application16/Actor1ActorService"));
_ = actor.GetCountAsync(default).GetAwaiter().GetResult();
ContinuationToken continuationToken = null;
var activeActors = new List<ActorInformation>();
var serviceName = new Uri("fabric:/Application16/Actor1ActorService");
using (var client = new FabricClient())
{
var partitions = client.QueryManager.GetPartitionListAsync(serviceName).GetAwaiter().GetResult();;
foreach (var partition in partitions)
{
var pi = (Int64RangePartitionInformation) partition.PartitionInformation;
var proxy = ActorServiceProxy.Create(new Uri("fabric:/Application16/Actor1ActorService"), pi.LowKey);
var page = proxy.GetActorsAsync(continuationToken, default).GetAwaiter().GetResult();
activeActors.AddRange(page.Items);
continuationToken = page.ContinuationToken;
}
}
Thread.Sleep(Timeout.Infinite);
请特别注意以下行:
_ = actor.GetCountAsync(default).GetAwaiter().GetResult();
这是发送给演员的第一条消息。
希望这会有所帮助。