2016-10-14 3 views
2

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

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

я тогда начать while цикл, который постоянно проверяет, чтобы увидеть, если некоторое значение достигло цели, в противном случае я awaitTask.Delay. Цикл имеет два условия выхода, если целевое значение достигнуто или если значение timeoutAndCancelTokenSource.IsCancellationRequested истинно.

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

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

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

+0

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

ответ

3

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

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

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

И ответ, чтобы исправить это:

Петля имеет два условия выхода, если будет достигнуто целевое значение, или если timeoutAndCancelTokenSource.IsCancellationRequested верно.

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

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

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

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

+0

Это в основном то, с чем я закончил, в конце концов.Спасибо, Стивен! – KDecker