我正在尝试在服务矩阵有状态服务中实现取消任务功能。
计划正在使用取消令牌将通知传播到链接的线程/任务。
问题是,尽管有这些长时间运行的任务和线程在等待该信号,但我不确定如何才能基于另一个Web API调用找到正确的取消令牌。
我当时正在考虑使用可靠的字典,然后甚至在尝试之前,我都认为这将陷入僵局,因为cancelingToken无法序列化/反序列化。
请帮助我,什么是解决此问题的好方法。
更新(我不想创建一个丢失该线程中提到的一些重要上下文的新线程,因此在本文中进行更新。)
确认下面的链接描述确实显示了可靠的服务和参与者方法可以支持取消令牌。但是,典型的用例是直接通过Web API通过用户触发(例如单击刷新,转到另一页面等)接收取消请求。在这种情况下,当先前的HTTP请求仍然存在时,需要使用完全相同的端点来接收请求。长时间运行的任务或卡住。那不是该线程中的场景。
对IService / IActor的CancellationToken支持
可靠的服务和可靠的Actor方法现在支持可以通过ActorProxy和ServiceProxy进行远程管理的取消令牌,从而使您可以实现协作取消。想要取消长期运行的服务或参与者方法的客户端可以发出取消令牌的信号,并且取消意图将传播到参与者/服务方法。然后,该方法可以通过查看其取消令牌参数的状态来确定何时停止执行。
例如,可以将具有可能长期运行的方法的演员合同建模如下:
public interface IPrimeNumberActorInterface : IActor
{
Task<ulong> FindNextPrimeNumberAsync
(ulong previous, CancellationToken cancellationToken);
}
希望取消方法执行的客户代码可以通过取消取消令牌来传达其意图。
答案 0 :(得分:3)
CancellationToken
和CancellationTokenSource
不可序列化,并且不会跨服务调用或SF中的数据复制流过。它只能用于告诉同一进程中的处理程序操作已被取消,并且应该停止任何处理或忽略任何继续,以防万一收到响应。
如果您希望能够启动和取消另一个服务中的操作,则应将操作分为两个调用。
CancellationTokenSource
,以生成一个CancellationToken
并传递给在后台运行的Task \ Thread。CancellationTokenSource
并取消它,以便提供给任何Task \ Thread的令牌可以停止任何处理(如果尚未完成或取消)。您可以简单地将其存储为Dictionary<Guid, CancellationTokenSource>
到运行任务的进程\分区中。
如果您正在SF的多个分区中运行这些任务,并计划将其存储在“可靠字典”中,则不是一个好主意,因为如前所述,您无法将取消序列化到其他分区。
在这种情况下,您可以存储OperationID和PartitionID,因此所有分区都知道操作在哪里运行,当您收到对任何分区的取消调用时,服务将在该操作所在的可靠字典中查找运行取消操作并将其转发到正确的分区。