Как гарантированно аннулируются аннулированные токены?
Microsoft дает этот пример CancellationToken
использовать в.NET 4.
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() =>
{
// Were we already canceled?
ct.ThrowIfCancellationRequested();
bool moreToDo = true;
while (moreToDo)
{
// Poll on this property if you have to do
// other cleanup before throwing.
if (ct.IsCancellationRequested)
{
// Clean up here, then...
ct.ThrowIfCancellationRequested();
}
}
}, tokenSource2.Token); // Pass same token to StartNew.
tokenSource2.Cancel();
// Just continue on this thread, or Wait/WaitAll with try-catch:
try
{
task.Wait();
}
catch (AggregateException e)
{
foreach (var v in e.InnerExceptions)
Console.WriteLine(e.Message + " " + v.Message);
}
Console.ReadKey();
}
}
Тем не менее, я понимаю, что если переменная изменяется в одном потоке, другой поток может не получить измененное значение из-за кэширования. И так как CancellationToken
отменяется в главном потоке, как это Task
нить заверил что CancellationToken
это проверка на самом деле актуальна?
Почему это невозможно для Task
читать кешированное значение токена?
Примечание: моя мотивация спрашивать об этом возникает из-за того, что мне нужно CancellationToken
переменные экземпляра, которые будут volatile
,
1 ответ
Это обрабатывается внутри CancellationTokenSource
, Закрытая переменная, используемая для отслеживания состояния CTS, помечена как volatile, что предотвращает устаревание внутренней проверки состояния.
Моя мотивация спрашивать об этом возникает из-за того, что мне нужны переменные экземпляра CancellationToken, чтобы они были изменчивыми.
Вам не нужно этого делать, так как проверка выполняется внутренне и уже для вас выполнена правильно.
В основном, когда вы создаете CancellationToken
от CancellationTokenSource
токен содержит ссылку на первоисточник. Эта ссылка никогда не может измениться, поэтому призыв к ThrowIfCancellationRequested
проверяет состояние источника внутри. Поскольку исходное состояние само по себе volatile
, это никогда не "устаревшие" данные.