Best Practice LongRunning Task creation

46,012

As you already mentioned, you can use the CancellationToken. Do it this way:

var cancellationTokenSource = new CancellationTokenSource();
Task.Factory.StartNew(RemoveFromBlockingCollection
                      , TaskCreationOptions.LongRunning
                      , cancellationTokenSource.Token);  

And later in your code, you can cancel the task with:

cancellationTokenSource.Cancel();

In your long running task you can ask the token, if cancellation was requested:

if (cancellationTokenSource.Token.IsCancellationRequested)
Share:
46,012

Related videos on Youtube

Jon
Author by

Jon

Updated on November 23, 2020

Comments

  • Jon
    Jon over 3 years

    Is this a good design for a background thread that needs to be run using the Task API in .Net 4? My only concern is if we want to cancel that task how I would do it? I know I can just set ProgramEnding to true but I know there is a CancellationToken in the Task API.

    This is just an example sample of code so that one thread will be adding to a collection and another thread will be removing from it. The Task is setup as LongRunning as this needs to be running continuously whilst the program is running

    private void RemoveFromBlockingCollection()
    {
        while (!ProgramEnding)
        {
           foreach (var x in DataInQueue.GetConsumingEnumerable())
           {
              Console.WriteLine("Task={0}, obj={1}, Thread={2}"
                              , Task.CurrentId, x + " Removed"
                              , Thread.CurrentThread.ManagedThreadId);
           }
        }
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
       DataInQueue = new BlockingCollection<string>();
       var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection
                                     , TaskCreationOptions.LongRunning);
    
       for (int i = 0; i < 100; i++)
       {
         DataInQueue.Add(i.ToString());
         Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
                           Task.CurrentId, i + " Added", 
                           Thread.CurrentThread.ManagedThreadId);
         Thread.Sleep(100);
       }
       ProgramEnding = true;
    }
    

    UPDATE: I have found that I can remove the ProgramEnding boolean and use DataInQueue.CompleteAdding which which bring the thread to an end.

  • Jon
    Jon over 12 years
    Is the use of a boolean to keep the thread alive a best practice or is there an API call? I have found I can use the CompleteAdding method on a BlockingCollection but if I'm not using a BlockingCollection and doing something else would the boolean be accpetable?
  • Fischermaen
    Fischermaen over 12 years
    Yes, it would work. Or you use the CancellationToken I mentioned above.
  • Jon
    Jon over 12 years
    I can use that to cancel the thread I was just asking your opinion to keep a thread running?
  • Fischermaen
    Fischermaen over 12 years
    To cancel a thread means to stop it from running. You have to check if (cancellationTokenSource.Token.IsCancellationRequested) in your thread coding to determine, if the thread should continue or stop. That's all, isn't it?
  • Jon
    Jon over 12 years
    Yup I understand but once you start a thread and it finishes its processes within it, it ends. I am wondering how you keep a thread alive. I simply used a boolean but didnt think it was elegant
  • Jon
    Jon over 12 years
    I guess I can do while(!cancellationTokenSource.Token.IsCancellationRequested‌​) { //do something}
  • Fischermaen
    Fischermaen over 12 years
    @Jon: sorry I didn't understand what you've meant. Yes, if you will have a thread that is running for an undefinite time, you will have to use a while-loop like this while(!cancellationTokenSource.Token.IsCancellationRequested‌​) { // do, what you have to do ... }
  • Jon
    Jon over 12 years
    Just a tip. The StartNew doesnt accept a CancellationTokenSource only a CancellationToken
  • Fischermaen
    Fischermaen over 12 years
    @Jon ... that's what I know. So I provided the .Token as parameter. ;-)
  • Matt Becker
    Matt Becker over 9 years
    I don't see the method signature for the StartNew method you're using in the TaskFactory documentation(msdn.microsoft.com/en-us/library/…). The only StartNew methods that take TaskCreationOptions and a CancellationToken also take a TaskScheduler.
  • Sudhanshu Mishra
    Sudhanshu Mishra over 8 years
    The general consensus on this thread: stackoverflow.com/questions/7343211/… is that the best way to exit out of the running task is to make a call to CancellationTokenSource.Token.ThrowIfCancellationRequested()