I want to cancel a running task (when the users presses the escape key).
when i click on "escape" key Form_KeyDown run but doesn't cancel task!
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token=new CancellationToken();
private async void Search_Button_ClickAsync(object sender, EventArgs e)
{
token = tokenSource.Token;
await (Task.Factory.StartNew(() =>
{
//...my program
},
token));
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
tokenSource.Cancel();
}
}
You are doing all ok except the fact that you need to stop your code from running inside your method. By passing cancellation token to Task.Factory.StartNew you are not aborting the task.
Let me quote Stephen Toub
:
Passing a token into StartNew associates the token with the Task.
This has two primary benefits: 1) If the token has cancellation
requested prior to the Task starting to execute, the Task won't
execute. Rather than transitioning to Running, it'll immediately
transition to Canceled. This avoids the costs of running the task if
it would just be canceled while running anyway. 2) If the body of the
task is also monitoring the cancellation token and throws an
OperationCanceledException containing that token (which is what
ThrowIfCancellationRequested does), then when the task sees that OCE,
it checks whether the OCE's token matches the Task's token. If it
does, that exception is viewed as an acknowledgement of cooperative
cancellation and the Task transitions to the Canceled state (rather
than the Faulted state).
You need to manually check if your token was cancelled and throw operation canceled exception, something along these lines:
private async void Search_Button_ClickAsync(object sender, EventArgs e)
{
cToken = cTokenSource.Token;
await (Task.Factory.StartNew(() =>
{
for(int i=0;i<yourtaskcount;i++)
{
cToken.ThrowIfCancellationRequested();
//long work
cToken));
}
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
tokenSource.Cancel();
}
}