Применить CancellationToken в dataflowblock


В моем приложении производитель-потребитель. У меня есть:

CancellationTokenSource cTokenSource = new CancellationTokenSource();
CancellationToken cToken = new CancellationToken();
cToken = cTokenSource.Token;

Нажмите кнопку Пуск, приложение запущено.

private async void Start_Click(object sender, RoutedEventArgs e)
{
   var producer = Producer();
   var consumer = Consumer();
   await Task.WhenAll(producer, consumer);
}

В потребителе я использовал TPL.

async Task Consumer()
{
    try
    {
        var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
        {
            MaxDegreeOfParallelism = 50,
            CancellationToken = cToken
        };
        var consumerBlock = new ActionBlock<AppointmentReminder>(
       remainder =>
       {
         // blah blah for long running processes and updating UI
          var result = Run(reminder);
       },
       executionDataflowBlockOptions);

        bufferBlock.LinkTo(
        consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });
        await Task.Delay(500);
    }

Теперь у меня есть кнопка отмены, я хочу остановить потребительские задачи TPL, пока я нажимаю ее. но как?

private void Cancel_Click(object sender, RoutedEventArgs e)
{
1 2

1 ответ:

Отмена в .Net является кооперативной. Вы создаете CancellationTokenSource для обработки отмены и используете CancellationToken для уведомления об отмене. Чтобы отменить токен, просто вызовите CancellationTokenSource.Cancel:

cTokenSource.Cancel();

Кстати, нет особого смысла создавать CancellationToken напрямую, поскольку его никогда нельзя отменить. Вы должны получить маркер от CancellationTokenSource:

var cTokenSource = new CancellationTokenSource();
var cToken = cTokenSource.Token;