C# How to cancel task

T.Zacks 3,986 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

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,648 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 61,731 Reputation points
    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