Answered by:
Cancelling Running Task without Async and Await

Question
-
Need to Cancel Running Task without Async and Await
Have 2 Buttons Start and Cancel & 1 Method.
private void button1_Click(object sender, EventArgs e) { CheckForIllegalCrossThreadCalls = false; var t = new Task(() => Testing()); t.Start(); } private void button2_Click(object sender, EventArgs e) { I Need to Cancel the Method testing while Running } private void Testing() { label1.Text = @"Processor running"; Thread.Sleep(9000); label1.Text = @"Processor Not running"; }
- Edited by ID GO Monday, November 14, 2016 2:23 PM
Monday, November 14, 2016 2:22 PM
Answers
-
Hello ID GO,
There are many examples on the net: https://msdn.microsoft.com/en-us//library/dd997364(v=vs.110).aspx?f=255&MSPPError=-2147217396
There are also many ways to accomplish. The newer examples tend to use Task instead of Thread.
The following is another example that might be helpful for your particular situation. I am doing this in a console app but the principle is similar. I will launch two tasks first (imagine launching one task per button1_click()). You could put the tasks and cancellation source in static variables. Then after return is pressed, a cancellation is sent that will stop both threads. This could be wired up to button2.
A couple of things to think about. You should make sure you dispose the CancellationTokenSource. Also, the Tasks will most likely need some parameters passed in (I show this in the example). Another thing to think about is when the Tasks do not take milliseconds to cancel. In this case a Task.WaitAll() would not be appropriate as it would block UI.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace ConsoleApplication1 { class Program { private class TestingParams { public CancellationToken token; public int id; } static void Main(string[] args) { // Create the token source. using (var cancellationTokenSource = new CancellationTokenSource()) { // Pass the token to the cancelable operation. var tasks = new Task<int>[] { Task<int>.Factory.StartNew(() => Testing(new TestingParams { id = 1, token = cancellationTokenSource.Token } )), Task<int>.Factory.StartNew(() => Testing(new TestingParams { id = 2, token = cancellationTokenSource.Token } )), }; Console.WriteLine("Press return to cancell."); Console.ReadLine(); // Request cancellation. cancellationTokenSource.Cancel(); Console.WriteLine("Cancellation set in token source ..."); Task.WaitAll(tasks); foreach(var task in tasks) { Console.WriteLine($"Task completed in {task.Result} iterations."); } Console.ReadLine(); } } private static int Testing(TestingParams testing) { int iterations = 0; while (!testing.token.IsCancellationRequested) { iterations++; Console.WriteLine($"Processor {testing.id} running"); Thread.CurrentThread.Join(300 * testing.id); } Console.WriteLine($"Processor {testing.id} Not running"); return iterations; } } }
Cheers, Jeff
- Proposed as answer by DotNet Wang Friday, November 18, 2016 8:19 AM
- Marked as answer by ID GO Friday, November 18, 2016 8:23 AM
Monday, November 14, 2016 9:19 PM
All replies
-
Monday, November 14, 2016 3:52 PM
-
Can you please provide me the code for the above exampleMonday, November 14, 2016 6:47 PM
-
Hello,
Why do you need an example re-typed when there was a link
provided that also contains an example? Just use the link and
read the information. Try the example also.
Monday, November 14, 2016 8:52 PM -
Hello ID GO,
There are many examples on the net: https://msdn.microsoft.com/en-us//library/dd997364(v=vs.110).aspx?f=255&MSPPError=-2147217396
There are also many ways to accomplish. The newer examples tend to use Task instead of Thread.
The following is another example that might be helpful for your particular situation. I am doing this in a console app but the principle is similar. I will launch two tasks first (imagine launching one task per button1_click()). You could put the tasks and cancellation source in static variables. Then after return is pressed, a cancellation is sent that will stop both threads. This could be wired up to button2.
A couple of things to think about. You should make sure you dispose the CancellationTokenSource. Also, the Tasks will most likely need some parameters passed in (I show this in the example). Another thing to think about is when the Tasks do not take milliseconds to cancel. In this case a Task.WaitAll() would not be appropriate as it would block UI.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace ConsoleApplication1 { class Program { private class TestingParams { public CancellationToken token; public int id; } static void Main(string[] args) { // Create the token source. using (var cancellationTokenSource = new CancellationTokenSource()) { // Pass the token to the cancelable operation. var tasks = new Task<int>[] { Task<int>.Factory.StartNew(() => Testing(new TestingParams { id = 1, token = cancellationTokenSource.Token } )), Task<int>.Factory.StartNew(() => Testing(new TestingParams { id = 2, token = cancellationTokenSource.Token } )), }; Console.WriteLine("Press return to cancell."); Console.ReadLine(); // Request cancellation. cancellationTokenSource.Cancel(); Console.WriteLine("Cancellation set in token source ..."); Task.WaitAll(tasks); foreach(var task in tasks) { Console.WriteLine($"Task completed in {task.Result} iterations."); } Console.ReadLine(); } } private static int Testing(TestingParams testing) { int iterations = 0; while (!testing.token.IsCancellationRequested) { iterations++; Console.WriteLine($"Processor {testing.id} running"); Thread.CurrentThread.Join(300 * testing.id); } Console.WriteLine($"Processor {testing.id} Not running"); return iterations; } } }
Cheers, Jeff
- Proposed as answer by DotNet Wang Friday, November 18, 2016 8:19 AM
- Marked as answer by ID GO Friday, November 18, 2016 8:23 AM
Monday, November 14, 2016 9:19 PM