I can't seem to wrap my head around how to properly start a task and cancel it. I've changed my code to be more simple to understand my issue and pasted it below (I've also added some comments). The SubscribeToReport method is called first - it contains an await runReportTask which from my understanding will just start the runReportTask method, wait for it to complete execution, then resume executing the code that appear after the await.
Inside runReportTask I create a CancellationTokenSource and start a new task using Task.Factory.StartNew(). Inside the task, there is a while loop that performs processing as long as the task hasn't been canceled. From my understanding, if cancellationToken.IsCancellationRequested is ever true, the else within my while loop will run and the task will stop. After that, I expect SubscribeToReport() to continue execution - this does not happen, and it doesn't ever seem like my code does anything when I call cancellationTokenSource.Cancel() in StopReportTask() . What am I doing wrong? I've been at this for a while and I just can't seem to wrap my head around how this is supposed to work.
private async static void SubscribeToReport()
{
Console.WriteLine("Waiting for task to finish or cancel...");
await runReportTask();
Console.WriteLine("Task has finished or was canceled."); // THIS LINE NEVER EXECUTES
}
private static CancellationTokenSource cancellationTokenSource;
private static CancellationToken cancellationToken;
private bool moreToDo = true;
private static Task runReportTask()
{
cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;
return Task.Factory.StartNew(() =>
{
// Were we already canceled?
cancellationToken.ThrowIfCancellationRequested();
while(moreToDo == true)
{
if(!cancellationToken.IsCancellationRequested)
{
// Do important code here
}
else{
Console.WriteLine("Task canceled."); // THIS LINE NEVER EXECUTES WHEN CALLING StopReportTask() below
cancellationToken.ThrowIfCancellationRequested();
break;
}
}
}, cancellationToken);
}
// This method is called from another source file
private void StopReportTask()
{
Console.WriteLine("Stopping report task...");
cancellationTokenSource.Cancel();
}
cancellationTokenSource.Cancel()is called on the same object? - CodingYoshistatic, so they are not part of a singleton. And given the code you posted, it is theoretically possible, if you callrunReportTask()again before the first task finishes, that the first task will never be canceled. It is also true, as you observe, that if the code is blocked, it can never get to a point of detecting the cancellation. If you want a real answer, you need to post a real minimal reproducible example that reliably reproduces the problem. There is not enough context here to know for sure what the issue is. - Peter Duniho