从客户端在RunAsync(CancellationToken)中手动调用Cancel

时间:2018-10-26 20:26:06

标签: azure-service-fabric service-fabric-stateful service-fabric-actor

在RunAsync(CancellationToken)后台方法中,当前代码正在生成新线程,并且在while(true)循环中还有一些长时间运行的任务。

公开了Web api控制器以提供取消请求,然后使用入队/出队,在RunAsync(cancellationToken)while(true)循环中访问此请求。

我只是无法在接收此取消请求的Web api控制器与将cancelken令牌传递到runasync方法内部运行的线程之间建立连接。

RunAsync(cancellationToken) 
{ 
   while(True)
   { 
     new thread(cancellationtoken)
   } 
} 

我很确定的一件事是,用户以某种方式调用的取消请求与作为RunAsync()的参数的cancelleToken之间没有连接,如上面的代码所示。似乎它们没有连接。我们不希望在用户取消请求时退出RunAsync()后台的永久循环,这仅适用于特定的线程运行。
请指导我正确的方向来设计终止线程的取消请求。

1 个答案:

答案 0 :(得分:1)

根据Peter Bons的建议,传递给RunAsync的取消令牌由Service Fabric创建和管理,以告知服务它正在关闭。当服务结构要在节点之间升级或移动服务时,您应该注意此取消操作,以使服务正常关闭。

另外一点是,您不会取消CancellationToken,而是取消CancellationTokenSource,因此,在这种情况下,您的代码创建的任何线程都应为每个要取消的线程创建一个自己的CancellationTokenSource单独,并且必须将CancellationTokenSource生成的令牌提供给线程,以便它知道何时取消该令牌。

另一点是,如果要使其平滑,则应使用CancellationTokenSource创建链接的CancellationTokenSource.CreateLinkedTokenSource(SFTokenPassedOnRunAsync),以便在Service Fabric想要关闭服务时,创建的主要取消令牌将取消所有子项。操作,否则您必须从代码中进行处理。

关于主要问题, 您只能在创建CancellationTokenSource的同一过程中取消操作。更简单的方法是在服务中公开端点(通过远程处理或通过Rest API),该端点将接收呼叫,找到令牌并取消操作。

会是这样的:

  • 服务创建CancellationTokenSource并使用生成的令牌启动新线程
  • CancellationTokenSource将存储在同一进程中可见的静态变量中,以便API可以看到
  • Api呼叫将获得此CancellationTokenSource并呼叫Cancel()

如果它是正在运行的操作(多线程)的列表,则可以将CTS存储在Dictionary中并为每个操作提供ID,然后可以根据操作的ID查找CTS。