locked
killing a task the proper way RRS feed

  • Question

  • HI Everybody,

    Here is the scenario: Suppose that I have two tasks that are making blocking
    calls to services that are taking a long time to respond.
    One gets done before the other, so I want that task to kill the others.
    I know that using abort is bad and evil, so what would be a good way to
    make this work?

    This is my test code:

            internal void Start ()
            {  
                CancellationTokenSource token_source_01 = new CancellationTokenSource ();
                CancellationTokenSource token_source_02 = new CancellationTokenSource ();
                CancellationToken CToken_stop_waiting_01 = token_source_01.Token;
                CancellationToken CToken_stop_waiting_02 = token_source_02.Token;
    
                Task
                do_nothing_task_01 = Task.Run
                ( () =>
                  {
                      Console.WriteLine ("I am pretending to make a blocking call (#1).");
                      //  Pretend that this ReadLine is a call to a service
                      //  that takes a long time to complete.
                      Console.ReadLine();
                      token_source_02.Cancel ();
                  },
                  CToken_stop_waiting_01
                );
    
                Task
                do_nothing_task_02 = Task.Run
                ( () =>
                  {
                      Console.WriteLine ("I am pretending to make a blocking call (#2).");
                      //  Pretend that this ReadLine is a call to a service
                      //  that takes a long time to complete.
                      Console.ReadLine();
                      token_source_01.Cancel ();
                  },
                  CToken_stop_waiting_02
                );
    
                Thread.Sleep (TimeSpan.FromSeconds (10));
                Console.WriteLine ("This will not actually kill the task.");
                token_source_01.Cancel ();
                Thread.Sleep (TimeSpan.FromSeconds (10));
                token_source_02.Cancel ();
    
                try
                {
                    do_nothing_task_01.Wait ();
                    do_nothing_task_02.Wait ();
                }
                catch (TaskCanceledException xcpt)
                {
                    Console.WriteLine($"{nameof(TaskCanceledException)} thrown with message: {xcpt.Message}");
                }
                catch (OperationCanceledException xcpt)
                {
                    Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {xcpt.Message}");
                }
                finally
                {
                    V_token_source.Dispose();
                }
       
                Console.WriteLine (" *** END");
                Console.ReadLine();
         }  
    

    THANKS!


    Wally

    Tuesday, September 22, 2020 9:30 PM

All replies

  • Consider CancelAfter. See Microsoft example.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, September 22, 2020 10:00 PM
  • Thanks for the suggestion.

    I cannot predict as to how long each task should take,
    and one of them must return something.

    Is there another approach?


    Wally

    Tuesday, September 22, 2020 11:04 PM
  • Thanks for the suggestion.

    I cannot predict as to how long each task should take,
    and one of them must return something.

    Is there another approach?


    Wally

    So you have absolutely zero idea how it will take? Seems there should be a range e.g. 1 second to 20 second, 30 minutes to two hours etc.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, September 22, 2020 11:06 PM
  • Thanks for the suggestion.

    I cannot predict as to how long each task should take,
    and one of them must return something.

    Is there another approach?


    Wally

    So you have absolutely zero idea how it will take? Seems there should be a range e.g. 1 second to 20 second, 30 minutes to two hours etc.

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    I have no idea.

    From what I've read in a few places,
    there doesn't seem to be any way to
    terminate a task without getting a
    reference to the thread from within
    the task and using Abort.

    Is that true?

    Is that safe?


    Wally

    Tuesday, September 22, 2020 11:23 PM
  • I am looking at this:

    https://www.c-sharpcorner.com/article/aborting-thread-vs-cancelling-task/


    Wally

    Tuesday, September 22, 2020 11:30 PM
  • I've had another thought: What is passed into
    the Task.Run method is  a delegate.

    Is there any way to stop the method that the
    delegate references from executing from outside
    of the executing thread?

    Would that be safe?


    Wally

    Tuesday, September 22, 2020 11:53 PM
  • I am looking at this:

    https://www.c-sharpcorner.com/article/aborting-thread-vs-cancelling-task/


    Wally

    See my code sample

    https://github.com/karenpayneoregon/async-cancellation-winforms/tree/master/CancellationToken


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Wednesday, September 23, 2020 2:59 AM