C #: CancellationToken does not cancel the lock method

.NET 4.5.1: It seems I can’t cancel the lock method running inside the task using the built-in CancellationTokenSource timeout.

class Program { static void Main(string[] args) { var cts = new System.Threading.CancellationTokenSource(); System.Console.CancelKeyPress += (s, e) => { e.Cancel = true; cts.Cancel(); }; MainAsync(args, cts.Token).Wait(); } // MainAsync from http://stackoverflow.com/questions/9208921/async-on-main-method-of-console-app static async Task MainAsync(string[] args, System.Threading.CancellationToken token) { Console.WriteLine("Starting MainAsync"); var cts = new System.Threading.CancellationTokenSource(3000); var task = Task.Factory.StartNew(() => { Console.WriteLine("Starting task..."); var t = new System.Net.Sockets.TcpClient(); var buffer = new byte[t.ReceiveBufferSize]; t.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 1337)); Console.WriteLine("Recieving..."); t.Client.Receive(buffer); Console.WriteLine("Finished Recieving..."); return true; }, cts.Token); var success = await task; Console.WriteLine("Did the task complete succesfuly?", success); } } 

Exiting the above short, self-preserving, correct example (I hope this is correct):

 Starting MainAsync Starting task... Recieving... 

Why the task does not cancel, the exception is not generated?

+7
c # task-parallel-library
source share
2 answers

As I state on my blog, β€œYou continue to use this CancellationToken . I don’t think it means what you think it means.”

In particular, the CancellationToken passed to StartNew only cancels the start of the delegate. If you want the delegate to support cancellation by himself, then the delegate himself will have to respect the CancellationToken .

+4
source share

I'm not sure, but I think you confuse the "cancellation request" with the "termination or interruption of the thread / task". These are two completely different things. According to the Canellation description in Managerd threads, the functionality provided allows you to send something like a signal, indicating that the operation being performed should be stopped.

How and if you react to this signal - as a programmer - is up to you.

In your example, you started a new task

 var task = Task.Factory.StartNew(() => { Console.WriteLine("Starting task..."); var t = new System.Net.Sockets.TcpClient(); var buffer = new byte[t.ReceiveBufferSize]; t.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 1337)); Console.WriteLine("Recieving..."); t.Client.Receive(buffer); Console.WriteLine("Finished Recieving..."); return true; }, cts.Token); 

which does not handle cancellation, and is not suitable for this. Channeling will be used, for example, if you want to break out of a loop with many iterations, so you should check each iteration if the CancellationToken.IsCancellationRequested value is set to true or not. If so, you can respond accordingly.

What you want is to interrupt the thread behind the current task, which, in my opinion, is possible only by creating a new instance of the Thread class for yourself and handle the interrupt accordingly.

+3
source share

All Articles