cancellationToken
CancellationToken
A cancellation token that can be used to cancel the work if it has not yet started. Run(Func, CancellationToken) does not pass cancellationToken to action.
From
here.
If you have an async method that you want to cancel, you need to provide a CancellationTokenSource to that method. Example:
public void ExecuteWithCancellationTokenSource(string path, CancellationTokenSource cancellationTokenSource)
{
foreach (var fileName in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
fileNameProgress.Report(fileName);
Thread.Sleep(1000);
if (cancellationTokenSource.IsCancellationRequested) break;
}
}
Otherwise, you can't cancel it if you have a method like this:
public void ExecuteWithoutCancellationTokenSource(string path)
{
foreach (var fileName in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
fileNameProgress.Report(fileName);
Thread.Sleep(1000);
}
}
and you start execution something like this:
Task task = Task.Run(() => { readFromHdd.ExecuteWithoutCancellationTokenSource(_path); }, _cancellationTokenSource.Token);
try
{
await Task.WhenAll(task);
}
catch (Exception ex)
{
tbFileNames.AppendText(ex.Message + Environment.NewLine);
}
finally
{
tbFileNames.AppendText("Done" + Environment.NewLine);
}
it will never stop. Or even worse, if you start like this:
Task task = Task.Run(() => { readFromHdd.ExecuteWithoutCancellationTokenSource(_path); }, _cancellationTokenSource.Token);
Task groupOfAllTasks = Task.WhenAll(task).ContinueWith(t =>
{
if (t.IsFaulted)
{
throw new Exception("rException!");
}
}, _cancellationTokenSource.Token);
List<Task> allTasks =
[
groupOfAllTasks
];
try
{
await Task.WhenAll(allTasks);
}
catch (Exception ex)
{
tbFileNames.AppendText(ex.Message + Environment.NewLine);
}
finally
{
tbFileNames.AppendText("Done" + Environment.NewLine);
}
It will raise a TaskCanceledException, but the operation will continue executing in the background.
Example download from
here.