中断演员-来自父服务的自定义取消令牌

时间:2018-11-02 17:15:19

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

使用作为参数传递的cancellingTokenSource生成线程。

RootStatefulService
{
    var cts= new CancellationTokenSource();
    ThreadStart starter = ()=> ParentMethod(Message.Value, cts);

    Thread t = new Thread(starter);
    t.Start();
    ...

    // When there is cancel request from client, below code runs
    cts.Token.Cancel();
}

在此ParentMethod中,正在创建Actor,然后再次尝试传递CancellationToken。

ParentMethod(SomeValue value, CancellationTokenSource cts)
{
    var actorWithToken = ActorProxy.Create<IActorWithToken>(
                      actorId,
                      new Uri(ActorWithTokenUrl));

    actorWithToken.StartLongRunningTask(someId, cts);

    cts.Token.Register(() => { StopImmediatelyAndTerminateActor});
}

这是自定义令牌,并且在客户端请求时,将调用RootStatefulService.cts.Cancel()。从有状态服务到参与者,我不确定是否提供了取消令牌源引用,以便将根服务中的Token.Cancel()调用向下传播到参与者Token.Register方法。我没有成功。并且,如果这不起作用,请回答正确的方法来调用自定义Token.Cancel()向下传播到生成的actor。

1 个答案:

答案 0 :(得分:0)

您不应创建线程来调用actor,代理实现应异步调用目标actor服务,而应使这些调用异步。

您使用的方法有很多缺陷。

  • CancellationTokenSource应该仅由一个所有者控制,您只应将其CancellationToken传递给被调用的方法。
  • 使用这种方法,您必须通过Thread.Abort()中止线程,但不向参与者发送取消请求。
  • 如果该方法没有在actorWithToken.StartLongRunningTask(someId, cts);操作中被阻塞以等待其完成,则该方法将完成执行,并且线程将完成。
  • 当取消发生在线程外时,cts.Token.Register(() => { StopImmediatelyAndTerminateActor});将在不再存在的上下文中调用StopImmediatelyAndTerminateActor方法,并可能导致许多难以识别的问题

关于代码,您应该能够像这样进行通话:

var cts = new CancellationTokenSource();

string uri = "fabric:/appName/ActorServiceName";
var actor = ActorProxy.Create<IMyActorInterface>(new ActorId(id), new Uri(uri));
Task<int> actorResut = actor.GetCountAsync(cts.Token);

//here you can manage what you want to do
//You could get the result like
var count = await actorResut;

//you can check if it has completed like this
if(actorResut.IsCompleted) {}

//you can cancel the task calling cancel on CTS
cts.Cancel();

这种方法对于长时间运行的操作有一些警告:

  • 只有呼叫者可以取消该操作,因为它将呼叫锁定到呼叫者,并且它必须处于活动状态才能取消远程操作。如果取消请求来自某个API,则您的请求必须始终转到启动该操作的同一实例,并且在大多数情况下,不能保证在负载均衡器后面并且您有很多实例在运行该负载均衡器。
  • actor操作有一个超时,该超时可以在操作完成之前取消操作,您可以增加它via settings
  • actor运行时中包含一些重试逻辑,当操作失败时将重试,您可以获得重复的处理请求。