我一直在寻找正确的方法来实现这种情况,没有任何运气。
这是针对特定客户端的多个长时间运行任务,假设在时间t0,t1和t2,在单个客户端中异步运行了三个任务。
Clients.Client(TheConnectionID).Task1(GUID1) //at t0
Clients.Client(TheConnectionID).Task1(GUID2) //at t1
Clients.Client(TheConnectionID).Task1(GUID3) //at t2
之后,从服务器(Hub)用户的请求被发送到从t1开始运行的任务。服务器知道在t1开始为Task1发送的GUID。
Clients.Client(TheConnectionID).Cancel(GUID2) //To cancel task started at t1
我试图将GUID与CancellationToken配对,并以某种方式抛出操作取消异常而没有运气。不知何故,抛出异常的线程似乎不是运行t1任务的正确线程..
请有人告诉我我做错了什么,或者如果在客户端使用信号器调用方法,这是不可能的。
回答我自己的问题似乎很尴尬,但我认为这对于类似情况的人来说可能是有价值的。根据我的观察,这个解决方案也可以带来进一步的讨论。
这是我发现的:
基于用户请求的调用:
Clients.Client(TheConnectionID).Cancel(GUID)
您可以根据客户端的特定任务处理取消例程:
try
{
concurrentCTSDictionary.TryGetValue(GUID, out CancellationTokenSource cts);
cts.Cancel();
}
实际的事件处理程序,它运行任务和令牌馈送:
async Task SomeMethodUserWantCancel([]args, CancellationToken ct)
{
// Option #1 or #2
}
现在这里有点奇怪,
当我使用选项#1时,包含抛出异常的线程没有在运行实际任务的同一线程上运行,并且即使抛出异常,任务仍保持运行。这就是我向stackoverflow发布问题的原因。
选项1:
using (var ctr = ct.Register(async () =>
{
ct.ThrowIfCancellationRequested();
}))
{
while (longtaskrunning)
{
await longTask();
}
}
选项#2工作并解决了我的问题:
while (longtaskrunning)
{
ct.ThrowIfCancellationRequested();
await longTask();
}