#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. Это в основном то, с чем я в итоге столкнулся. Спасибо, Стивен!