I have a producer-consumer application, I wrote it as a WPF. For the convince, I set the project's property as console, so I can simply using Console output.
Basically I add integers to a BufferBlock queue in producer, when I click the Start button, it runs producer and consumer. Now I want to cancel it by clicking cancel button then displaying "Stop" . So I passed CancellationToken to the method but it is not working, which means it keeps send the output.
The main code:
public static BufferBlock<int> queue = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1000 });
private CancellationTokenSource cTokenSource;
private static CancellationToken cToken;
private void Start_Click(object sender, RoutedEventArgs e)
{
cTokenSource = new CancellationTokenSource();
cToken = cTokenSource.Token;
var producer = Producer();
var consumer = Consumer();
}
async Task Consumer()
{
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 1,
CancellationToken = cToken
};
var consumerBlock = new ActionBlock<int>(
i =>
{
if (cToken.IsCancellationRequested)
return;
RunScript(i, cToken); Dispatcher.BeginInvoke((Action)delegate()
{
items.Add(new TodoItem() { Number = i });
});
},
executionDataflowBlockOptions);
queue.LinkTo(
consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });
await consumerBlock.Completion;
}
private void RunScript(int i, CancellationToken cToken)
{
Console.WriteLine("Processing " + i);
for (int j = 0; j < 100; j++)
{
Console.WriteLine(j);
Thread.Sleep(1000);
}
Console.WriteLine("------------");
cToken.Register(() =>
{
Console.WriteLine("Stop");
return;
});
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
cTokenSource.Cancel();
}I also provided a full clean solution on the OneDrive.
The file name is "CancellationTokenIsNotWorking.zip". Thanks for help.