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

Invoke Cancel manually from client side in RunAsync(CancellationToken)

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

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

我无法在接收此取消请求的 Web api 控制器与传递到 运行 异步方法内的线程 运行ning 的取消请求之间建立连接。

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

我非常确定的一件事是,用户以某种方式调用的取消请求与作为 RunAsync() 参数的 cancellationToken 之间没有任何联系,如上面的代码所示。似乎他们没有联系。我们不想在用户取消请求时跳出 RunAsync() 后台的永远循环,这仅适用于特定线程 运行.
请指导我正确设计取消请求终止线程的方向。

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

另外一点是,你没有取消 CancellationToken,你取消了 CancellationTokenSource,所以在这种情况下,你的代码创建的任何线程都应该为每个线程创建一个自己的 CancellationTokenSource被单独取消并且由此 CancellationTokenSource 生成的令牌必须提供给线程以便它知道它何时被取消。

还有一点,如果你想让它顺利,你应该使用CancellationTokenSource.CreateLinkedTokenSource(SFTokenPassedOnRunAsync)创建一个链接CancellationTokenSource,这样当Service Fabric想要关闭服务时,创建的主要取消令牌将取消任何子操作,否则你必须从你的代码中处理它。

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

会是这样的:

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

如果是运行个操作的列表(多线程),你可以把CTS存储在一个Dictionary中,给每一个操作赋予ID,然后你就可以根据操作的ID找到CTS操作。