Я запускаю связанную с процессором задачу в приложении asp.net mvc.Некоторые пользователи могут «подписаться» на эту задачу, и они должны быть уведомлены о завершении.Но если у задания нет подписчиков, оно должно быть отменено.Задача запускается через ajax-запрос и отменяется при вызове метода .abort ().В контроллере у меня есть CancellationToken в качестве параметра, который определяет отмену.
Проблема в том, что когда один из абонентов вызывает прерывание (отписывается), связанный токен отменяет задачу, несмотря на то, что другие пользователи ждут результата.Как я могу отменить CancellationToken после проверки некоторых условий?Я не могу проверить реквизиты IsCancellationRequested после каждой итерации цикла, потому что я обертываю не асинхронный метод.
Пользователи получают уведомление с SignalR после завершения задачи.Я попытался реализовать ConcurrentDictionary, чтобы проверить перед отменой, есть ли у задачи подписчики или нет.
private async Task<Diff> CompareAsync(Model modelName, CancellationToken ct)
{
try
{
return await Task.Factory.StartNew(() =>
{
ct.ThrowIfCancellationRequested();
return _someServiceName.CompareLines(modelName.LinesA, modelName.LinesB, ct);
}, ct, TaskCreationOptions.LongRunning, TaskScheduler.Default).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
//do some things
}
}
Мне нужно что-то подобное, но я не могу придумать (не уродливые) идеи:
private async Task<Diff> CompareAsync(Model modelName, CancellationToken ct)
{
try
{
return await Task.Factory.StartNew(() =>
{
using (var source = new CancellationTokenSource())
{
if (ct.IsCancellationRequested && CompareService.SharedComparison.TryGetValue(modelName.Hash, out var usersCount) && usersCount < 2)
{
source.Cancel();
}
return _someServiceName.CompareLines(modelName.LinesA, modelName.LinesB, source.Token);
}
}, ct, TaskCreationOptions.LongRunning, TaskScheduler.Default).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
//do some things
}
}