Остановка CancellationTokenSource, время ожидания которого истекает через заданный промежуток времени, чтобы сохранить его состояние?

#c# #task-parallel-library

#c# #задача-параллельная-библиотека

Вопрос:

У меня есть метод, который принимает a CancellationToken , который позволяет пользователю метода отменить то, что он делает. В рамках метода я использовал это CancellationToken вместе с a CancellationTokenSource для создания связанного CancellationTokenSource .

 var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(msTimeout));
var timeoutAndCancelTokenSource = CancellationTokenSource.CreateLinkedTokenSource(
        timeoutTokenSource.Token, cancelWaitToken);
 

Затем я запускаю while цикл, который постоянно проверяет, достигло ли какое-либо значение целевого значения, в противном случае я await a Task.Delay . Цикл имеет два условия выхода, если достигнуто целевое значение или если значение timeoutAndCancelTokenSource.IsCancellationRequested true .

Когда цикл завершается, я могу опросить timeoutTokenSource и cancelWaitToken определить, был ли цикл отменен в результате тайм-аута, он был отменен или было достигнуто целевое значение.

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

Есть ли способ остановить a, чтобы он не прерывался? CancellationTokenSource

Комментарии:

1. Кроме установки тайм-аута, передается ли какой-либо другой метод CancellationTokenSource для отмены токена вручную?

Ответ №1:

Есть ли способ остановить CancellationTokenSource, чтобы он не прерывался?

Неправильный вопрос. (Кстати, остановить его невозможно).

Правильным вопросом было бы «Как мне определить, был ли цикл отменен в результате тайм-аута, он был отменен или было достигнуто целевое значение?»

И ответ заключается в том, чтобы исправить это:

Цикл имеет два условия выхода, если достигнуто целевое значение или если время ожидания и canceltokensource .IsCancellationRequested имеет значение true .

Ваш цикл должен завершаться только при достижении целевого значения. Он должен передать (связанный) CancellationToken в Task.Delay .

Затем, когда вы catch OperationCanceledException проверяете, вы проверяете свой cancelWaitToken и timeoutTokenSource.Token , чтобы увидеть, какой из них отменен.

Итак, если до истечения времени ожидания осталось всего несколько миллисекунд, я мог бы сделать ложные предположения о том, что произошло внутри цикла.

ДА. Если вы измените условие выхода из цикла, вы будете знать только, достигло ли оно своего целевого значения или нет. Возможно, что к моменту их проверки могут быть сигнализированы оба токена отмены, но я считаю, что это благоприятное условие гонки. Если cancelWaitToken сигнализируется, действительно ли имеет значение, истекло ли время ожидания?

Комментарии:

1. Это в основном то, с чем я в итоге столкнулся. Спасибо, Стивен!