【发布时间】:2019-10-25 15:20:47
【问题描述】:
我在 asp.net mvc 应用程序中运行 cpu-bound 任务。一些用户可以“订阅”此任务,并且应该通知他们完成。但是当任务没有订阅者时,它必须被取消。任务通过 ajax 请求启动,并在调用 .abort() 方法时取消。在控制器中,我将 CancellationToken 作为确定取消的参数。
问题在于,当其中一个订阅者调用 abort(取消订阅)时,链接的令牌会取消任务,尽管其他用户正在等待结果。检查某些条件后如何取消 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
}
}
【问题讨论】:
标签: c# asp.net-mvc concurrency