This is the way it worked to me. I used a progressBar to see my async task is still running. The task really runs async to the GUI Task. I can enter values in my richTextBox, click buttons or whatever, while the bar still runs on. Because of the different threads the bar treatment must be done with Invoke to avoid a cross-thread operation exception.
private CancellationTokenSource cancellationToken; private async void btnRun_Click(object sender, EventArgs e) { progressBar1.Value = 0; cancellationToken = new CancellationTokenSource(); await Task.Run(() => { workFunction(progressBar1); }, cancellationToken.Token); rtbResult.Text += "finished work function :-)\n"; } private void workFunction(ProgressBar bar) { for (int i = 0; i < 25; i++) { Thread.Sleep(500); bar.BeginInvoke(new Action(() => { bar.Value += 400; })); if(cancellationToken.IsCancellationRequested) { return; } } } private void btnCancel_Click(object sender, EventArgs e) { if(cancellationToken != null) { cancellationToken.Cancel(); } }
The cancellation must be handeled in the work function, as Sasha said here How to use the CancellationToken without throwing/catching an exception?