Reputation: 13
I have Two button for scenarios where one initiate the task and other stop that task.
// this is the property which is used to cancel the task
CancellationTokenSource cTokenSource;
private async void OnReadCommand()
{
cTokenSource = new CancellationTokenSource();
ReadAction();
}
private async void ReadAction()
{
Task.Factory.StartNew(() => {
while (true)
{
Task.Delay(TimeSpan.FromSeconds(2)).Wait();
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
}
},cTokenSource.Token);
}
private async void OnCancelCommand()
{
// it's used to cancel the task
cTokenSource.Cancel();
}
my app is wpf and using mvvm pattern and prism library. while calling the OnCancelCommand the task is running in background and printing the GUID. I have to cancel the task only and only on OnCancelCommand.
Upvotes: 1
Views: 737
Reputation: 4428
You need to implement the code for exiting the loop yourself:
private async void ReadAction()
{
Task.Factory.StartNew(() => {
while (true)
{
Task.Delay(TimeSpan.FromSeconds(2)).Wait();
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
cTokenSource.Token.ThrowIfCancellationRequested();
}
},cTokenSource.Token);
}
or
private async void ReadAction()
{
Task.Factory.StartNew(() => {
while (true)
{
Task.Delay(TimeSpan.FromSeconds(2)).Wait();
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
if (cTokenSource.Token.IsCancellationRequested)
{
break; // or return;
}
}
},cTokenSource.Token);
Usage examples you can find in the documenation Task Class. The only benefit that you get from passing CancellationToken to StartNew method is that it can automatically cancel the task for you if the source is cancelled before the task started. However to cancel it during the run you need to code the logic yourself. Here is another good reading on that https://stackoverflow.com/questions/48312544/whats-the-benefit-of-passing-a-cancellationtoken-as-a-parameter-to-task-run#:~:text=In%20summary%2C%20providing%20the%20cancellation,to%20start%20running%20the%20task.
Furthermore, I would suggest to you using await in the logic that you execute in StartNew so that you do not loose the benefits of being asynchronous:
private async void ReadAction()
{
Task.Factory.StartNew(async () => {
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(2));
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
if (cTokenSource.Token.IsCancellationRequested)
{
break; // or return;
}
}
},cTokenSource.Token)
That way threads will no longer get blocked and will be released during a call to Delay.
Upvotes: 1