In the following code, if the UserCancelled
property is set to true, I want it to end the loop immediately and continue code.
The problem I'm facing is it continues after the 6 seconds passes, not before, which I thought the cancellation token would end the delay early.
What are the options to end this delay sooner?
CancellationTokenSource _source = new CancellationTokenSource();
var token = _source.Token;
foreach (var mock in lst)
{
if (UserCancelled)
{
_source.Cancel();
_source.Dispose();
break;
}
label1.Text = mock.Name;
await Task.Delay(6000, token);
}
label1.Text = " Broke Out";
CodePudding user response:
It's because the cancellation is not requested until the continuation is executed after waiting for 6 seconds. Extract the cancellation source into a field and call _source.Cancel()
at the moment you set UserCancelled
to true.
label1
gives me the hint this is some sort of UI code so I would refactor it something like this:
// this is a field
private CancellationTokenSource _source = new CancellationTokenSource();
// call this from whatever handler/command and pass _source.Token to it:
private async Task DoMyTaskAsync(CancellationToken token)
{
foreach (var mock in lst)
{
if (token.IsCancellationRequested)
break;
label1.Text = mock.Name;
await Task.Delay(6000, token);
}
label1.Text = " Broke Out";
}
// can be a simple event handler, too (eg. for some btnCancel.Click)
private void OnCancelCommand()
{
// avoid double cancellation and ObjectDisposedException
if (UserCancelled)
return;
_source.Cancel();
_source.Dispose();
UserCancelled = true;
}
CodePudding user response:
If UserCancelled
is already set to true
when we enter the loop, then you should cancel immediately.
If UserCancelled
was false
on initial check then you go to the Task.Delay
and start waiting. No any additional checks are performed during the wait.
After 60s the work resumes and you go on then next iteration of the loop. And here, again, if f UserCancelled
is set to true
, you will cancel and exit, else will wait for another 60s.
The best solution here will be to make the _source
variable available to the code, which is setting UserCancelled
. And such a code will call _source.Cancel()
directly.