C# How to cancel task

T.Zacks 3,996 Reputation points
2022-10-28T14:11:10.537+00:00

Suppose using task i am firing a routine which is long running. i want when user cancel task then long running routine will stop and task will be canceled.
this way i tried but not able to compose code properly. so please see my code and change it to get desired output.

class SingleThreadTaskScheduler : TaskScheduler  
    {  
        public Thread TaskThread { get; private set; }  
  
        protected override void QueueTask(Task task)  
        {  
            TaskThread = new Thread(() => TryExecuteTask(task));  
            TaskThread.Start();  
        }  
  
        protected override IEnumerable<Task> GetScheduledTasks() => throw new NotSupportedException(); // Unused  
        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) => throw new NotSupportedException(); // Unused  
    }  

Calling the code this way

        SingleThreadTaskScheduler scheduler = null;  
        CancellationToken ct;  
        CancellationTokenSource ts = new CancellationTokenSource();  
         
        private void button3_Click(object sender, EventArgs e)  
        {  
            //start the task  
            ct = ts.Token;  
            scheduler = new SingleThreadTaskScheduler();  
            var task = Task.Factory.StartNew(Test, ct, TaskCreationOptions.LongRunning, scheduler);  
        }  
  
        private void Test()  
        {  
            if (this.labelControl1.InvokeRequired)  
            {  
                this.labelControl1.BeginInvoke((MethodInvoker)delegate () { this.labelControl1.Text = "Task Start"; });  
            }  
  
            System.Threading.Thread.Sleep(10000);  
        }  
  
        private void button4_Click(object sender, EventArgs e)  
        {  
            //Cancel the task  
            scheduler.TaskThread.Abort();  
            if (ct.IsCancellationRequested)  
            {  
                if (this.labelControl1.InvokeRequired)  
                {  
                    this.labelControl1.BeginInvoke((MethodInvoker)delegate () { this.labelControl1.Text = "Task Cancel"; });  
                }  
            }  
            else  
            {  
                ts.Cancel();  
            }  
        }  

please tell me what is wrong in there. if possible guide me with easy approach to cancel running task if any exist. thanks

Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2022-10-28T20:51:23.99+00:00

    you are confusing Cancellation (controlled exit) with abort.

    • abort kills a thread and thows thread exception. all variables, especially statics are left in an unknown state.
    • cancellation is a message to a thread to gracefully exit.

    for Cancellation to work, the thread must implement support for cancelation. say in your code:

     private void Test()  
     {  
                 if (this.labelControl1.InvokeRequired)  
                 {  
                     this.labelControl1.BeginInvoke((MethodInvoker)delegate () { this.labelControl1.Text = "Task Start"; });  
                 }  
       
                 for (var I=0; I < 10000; ++i)  
                 {  
                         if (ct.IsCancellationRequested)  
                         {  
                                ct.ThrowIfCancellationRequested();  
                                return;  
                         }  
                         System.Threading.Thread.Sleep(1);  
                 }  
     }  
    

    then in the

            private void button4_Click(object sender, EventArgs e)  
             {  
                 //Cancel the task  
                 ts.Cancel();  
      
                if (this.labelControl1.InvokeRequired)  
                 {  
                         this.labelControl1.BeginInvoke((MethodInvoker)delegate () { this.labelControl1.Text = "Task Cancel"; });  
                 }  
             }  
    

    you might want to add a watchdog timer to abort the task if it does not gracefully exit


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.