locked
How to abort and then probably restart awaitable Task<T>

    Question

  •         public void StartWork()
            {
                for (int i = 0; i < 30; i++)
                {
                    DoWork(i);
                }
            }
    
            public void AbortWork()
            {
                //Here i want to abort the work.. _cancellationTokenSource.Cancel();
    
                /*
                    Aim 1 : I want to abort in such a way that PopulateData does not get called for any Tasks in progress. 
                 *  Aim 2 : I should be able to StartWork Again.. 
                 * */
            }
    
            CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
            private async void DoWork(int i)
            {
                List<string> result;
    
                //Ideally would want to use TaskCreationOptions.LongRunning here & create the task
                result = await Task<List<string>>.Factory.StartNew(() => DoLongRunningWork(i), _cancellationTokenSource.Token);
    
                //Back on Main/UI Thread do .. If tasks canceled this should not be called.
                PopulateData(result);
            }
    
            private void PopulateData(List<string> result)
            {
                throw new NotImplementedException();
            }
    
            public List<string> DoLongRunningWork(int i)
            {
                Thread.Sleep(5000);
                return new List<string>() { "John","Mary", "Bruce", "Lamb"};
            }

    I am working on creating a class that will be used in a WPF application which will handle some long running tasks. The user wants the ability to start long running tasks and get a loading.. feedback ..  This is all fine and easy with the async await and TPL. 

    Now i am trying to fulfill the requirement of giving the user the ability to cancel the requested operation. Now by then we could have several InProgress Tasks... I would like to cancel them ALL AbortWork(). Also if the desires can do StartWork() and try it again.. 

    I am trying to work out the best way to Cancel tasks. 

    Many thanks! 


    Monday, October 8, 2012 9:18 AM

Answers

  • Basically, there are two ways to handle canceling:

    In your case, I think you should use a combination of the two approaches: call ThrowIfCancellationRequested() just before you call PopulateData(), and also pass it as a parameter into DoLongRunningWork(), so that the long running work can be canceled in the middle of execution (or not, if it calls some long-running method than cannot be canceled).

    And BTW, the code you use to start your Task could be shortened by using Task.Run().

    • Marked as answer by bobragland Tuesday, October 9, 2012 10:13 AM
    Monday, October 8, 2012 10:23 AM