I have been playing round with the Async CTP
this morning and have a simple program with a button
and a label
. Click the button
and it starts updating the label
, stop the button
it stops writing to the label
. However, I'm not sure how to reset the CancellationTokenSource
so that I can restart the process.
My code:
public partial class MainWindow : Window { CancellationTokenSource cts = new CancellationTokenSource(); public MainWindow() { InitializeComponent(); button.Content = "Start"; } async Task DoWork(CancellationToken cancelToken) { int i = 0; while (!cancelToken.IsCancellationRequested) { label.Content = i++.ToString(); await TaskEx.Delay(50, cancelToken); } } private void Button_Click(object sender, RoutedEventArgs e) { if (button.Content == "Start") { button.Content = "Stop"; DoWork(cts.Token); } else { button.Content = "Start"; cts.Cancel(); } } }
CancellationTokenSource is quite a heavyweight object and its not normally cancelled; however it can't be pooled or reused because its registrations cannot be cleared.
The Dispose method leaves the CancellationTokenSource in an unusable state. After calling Dispose , you must release all references to the CancellationTokenSource so the garbage collector can reclaim the memory that the CancellationTokenSource was occupying.
A CancellationToken can only be created by creating a new instance of CancellationTokenSource . CancellationToken is immutable and must be canceled by calling CancellationTokenSource. cancel() on the CancellationTokenSource that creates it. It can only be canceled once.
So CancellationToken can be used to terminate a request execution at the server immediately once the request is aborted or orphan. Here we are going to see some sample code snippets about implementing a CancellationToken for Entity FrameworkCore, Dapper ORM, and HttpClient calls in Asp. NetCore MVC application.
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With