SignalR просто завершает единственную длительную задачу среди многих в пределах определенного клиента

#signalr #signalr.client

#signalr #signalr.client

Вопрос:

Я безуспешно искал правильную методологию для достижения этого сценария.

Это касается нескольких длительно выполняющихся задач для конкретного клиента, допустим, в одном клиенте асинхронно выполнялись три задачи во время 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.
Сервер знает идентификатор GUID, отправленный для Задачы1, запущенной в t1.

 Clients.Client(TheConnectionID).Cancel(GUID2)  //To cancel task started at t1
  

Я попытался связать GUID с CancellationToken и каким-то образом создать исключение отмены операции, но безуспешно. Почему-то поток, в котором сгенерировано исключение, кажется неправильным потоком, в котором выполняется задача t1..

Пожалуйста, кто-нибудь, просветите меня, что я делаю неправильно, или если это невозможно с помощью методов вызова signalr на стороне клиента.

Ответ №1:

Отвечать на мой собственный вопрос кажется неудобным, но я думаю, что это может быть полезно для кого в подобной ситуации. Также это решение с моими наблюдениями могло бы привести к дальнейшему обсуждению, проливающему некоторый свет.

Вот что я нашел:

На основе запроса пользователя:

  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();
}