Как реализовать отменяемый рабочий поток

Я пытаюсь реализовать отменяемый рабочий поток, используя новые конструкции потоков в пространстве имен System.Threading.Tasks. До сих пор я придумал эту реализацию:

public sealed class Scheduler
{
    private CancellationTokenSource _cancellationTokenSource;
    public System.Threading.Tasks.Task Worker { get; private set; }

    public void Start()
    {
        _cancellationTokenSource = new CancellationTokenSource();

        Worker = System.Threading.Tasks.Task.Factory.StartNew(
            () => RunTasks(_cancellationTokenSource.Token),
             _cancellationTokenSource.Token
        );
    }

    private static void RunTasks(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            Thread.Sleep(1000); // simulate work
        }
    }

    public void Stop()
    {
        try
        {
            _cancellationTokenSource.Cancel();
            Worker.Wait(_cancellationTokenSource.Token);
        }
        catch (OperationCanceledException)
        {
            // OperationCanceledException is expected when a Task is cancelled.
        }
    }
}

когда Stop() Я ожидаю возвращения Worker.Status быть TaskStatus.Canceled,
Мои юнит-тесты показали, что при определенных условиях Worker.Status остается установленным TaskStatus.Running,

Это правильный способ реализации отменяемого рабочего потока?

1 ответ

Решение

Я считаю, что проблема в вашем звонке

Worker.Wait(_cancellationTokenSource.Token);

Это ждет, пока токен не будет сигнализирован - это уже есть, потому что вы только что позвонили Cancel(), Если вы измените это просто

Worker.Wait();

тогда я верю, что вы увидите состояние RanToCompletion, Вы не увидите Отменено, потому что ваша задача не бросает OperationCanceledException, Если вы измените свой RunTasks метод для вызова

cancellationToken.ThrowIfCancellationRequested()

в конце, то вам нужно поймать AggregateException в Stop - но тогда вы увидите состояние Canceled в конце.

По крайней мере, так показывают мои эксперименты:)

Другие вопросы по тегам