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