How to reset a CancellationToken properly?
You need to recreate the CancellationTokenSource
- there is no way to "reset" this once you set it.
This could be as simple as:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (button.Content == "Start")
{
button.Content = "Stop";
cts.Dispose(); // Clean up old token source....
cts = new CancellationTokenSource(); // "Reset" the cancellation token source...
DoWork(cts.Token);
}
else
{
button.Content = "Start";
cts.Cancel();
}
}
I had the same problem and I figured it out that the best way to solve it is to create cancellation token source newly just before calling the method.
this is what I do on my start button click:
cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;
Task.Factory.StartNew(StartUpload, cancellationToken);
I change the caption for the same button to cancel and when a click occurs on cancel, I call
cancellationTokenSource.Cancel();
Here is the full code:
if (button3.Text != "&Start Upload")
{
cancellationTokenSource.Cancel();
}
else
{
try
{
cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;
Task.Factory.StartNew(StartUpload, cancellationToken);
}
catch (AggregateException ex)
{
var builder = new StringBuilder();
foreach (var v in ex.InnerExceptions)
builder.Append("\r\n" + v.InnerException);
MessageBox.Show("There was an exception:\r\n" + builder.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Now, with .NET 6 you can use TryReset()
method which Attempts to reset the CancellationTokenSource to be used for an unrelated operation.
see this issue and CancellationTokenSource.cs for more details.