我一直在寻找正确的方法来实现这种情况,而没有任何运气。
这涉及到特定客户端的多个长时间运行的任务,比方说,在时间t0,t1和t2,单个客户端中有三个异步运行的任务。
Clients.Client(TheConnectionID).Task1(GUID1) //at t0
Clients.Client(TheConnectionID).Task1(GUID2) //at t1
Clients.Client(TheConnectionID).Task1(GUID3) //at t2
后来,来自服务器(集线器)的用户请求被发送到从t1开始运行的任务。 服务器知道从t1开始为Task1发送的GUID。
Clients.Client(TheConnectionID).Cancel(GUID2) //To cancel task started at t1
我尝试将GUID与CancellationToken配对,并以某种方式抛出操作取消了异常,但没有运气。以某种方式抛出异常的线程似乎不是运行t1 Task的正确线程。
请有人告诉我我做错了什么,或者如果用客户端上的signalr invoke方法永远不可能做到这一点。
答案 0 :(得分:0)
回答我自己的问题似乎很尴尬,但我认为这对处于类似情况的人可能很有价值。同样,根据我的观察结果,这种解决方案可能会带来进一步的讨论。
这是我所发现的:
基于用户请求的调用:
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();
}