-1

I have an async method. I do not have access to the Frame.Execute() code method.

Issue: myTask would not cancel until the Frame.Execute complete execution.

I need to immediately cancel Frame.Execute() and myTask when a cancellation requested.

private async Task myTask(CancellationToken tkn)
{
tkn.ThrowIfCancellationRequested();
var myList=  await Task.Run(()=> Frame.Execute(),tkn);

//Do other things
}
Rick
  • 55
  • 1
  • 12
  • 3
    Once ```Frame.Execute()``` is running there is no way to cancel it unless the method itself supports cancellation and has an override that accepts a cancellation token. All you're doing there is passing the cancellation token into ```Task.Run``` but not actually using it. – pmcilreavy Dec 28 '17 at 20:59
  • Task cancellation via CancellationToken is a cooperative model, i.e. code using it must be written to explicitly stop itself when it is safe to do so. If some external code does not support cooperative cancellation then you are just out-of-luck. If Frame supports some other kind of mechanism like an Abort method, you can use CancellationToken.Register to register a callback that will be invoked when the token is cancelled. – Mike Zboray Dec 28 '17 at 22:55

3 Answers3

0

The fact you receive CancellationToken as input parameter usually means that the token is controlled by outer code. So, the code snippet you've composed exposes following assumptions:

  1. A task was created by outer code, and your first line (ThrowIfCancellationRequested) is absolutely legit - if the token is in "canceled" state, your code would stop the task right here.
  2. If not canceled so far, your task then runs a new task (child task) that receives the same token as input parameter, and this is absolutely legit - so once signaled the token could terminate entire subtree of both tasks.

The only wrong thing, as mentioned by @pmcilreavy comment, is the child task code should check for token state too. Otherwise, no cancellation here, sorry.

P.S. You may find this MSDN link useful: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children

Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42
0

Frame.Execute doesn't appear to be async from what I can see that you've posted. What you are doing is starting a synchronous process in a new Task. The cancellation token you pass is only relevant to the task you've created but the Frame.Execute method doesn't get passed the cancellation token and won't pay attention to it. It most likely doesn't have an overload that accepts one as it doesnt appear to be async. So once Frame.Execute begins it won't return until it finishes at this point the task you have created gets control back and then it pays attention to your cancelled Token

Dave
  • 2,829
  • 3
  • 17
  • 44
0

hi try this write the ThrowIfCancellationRequested after the call to Frame.Execute() code method and don't send the cancelation token in the taks call, instead of that, outside of the method after the call to myTask you can use the cancellationTokenSource.Cancel(), look the next example code.

using System;
using System.Threading;
using System.Threading.Tasks;

CancellationTokenSource cancellationTokenSource =
new CancellationTokenSource();

CancellationToken tkn = cancellationTokenSource.Token;

private async Task myTask(CancellationToken tkn)
{
    Console.WriteLine("Hi now i'm inside the Task");    
    var IsOut =  await Task.Run(()=> {
        while(true)
                {
                    Console.Write("*");
                    Thread.Sleep(500);
                }
        return true;
        });
    tkn.ThrowIfCancellationRequested();
    Console.WriteLine("This code not execute");
//Do other things
}

Console.WriteLine("Before to invoke the Taks");
Task.Run(()=> myTask(tkn));
Thread.Sleep(3000);
cancellationTokenSource.Cancel();
Console.WriteLine("");
Console.WriteLine("The End ");