Best Practice LongRunning Task creation
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)
Related videos on Youtube
Jon
Updated on November 23, 2020Comments
-
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
totrue
but I know there is aCancellationToken
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 over 12 yearsIs 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 over 12 yearsYes, it would work. Or you use the CancellationToken I mentioned above.
-
Jon over 12 yearsI can use that to cancel the thread I was just asking your opinion to keep a thread running?
-
Fischermaen over 12 yearsTo 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 over 12 yearsYup 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 over 12 yearsI guess I can do while(!cancellationTokenSource.Token.IsCancellationRequested) { //do something}
-
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 over 12 yearsJust a tip. The StartNew doesnt accept a CancellationTokenSource only a CancellationToken
-
Fischermaen over 12 years@Jon ... that's what I know. So I provided the
.Token
as parameter. ;-) -
Matt Becker over 9 yearsI 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 over 8 yearsThe 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()