Why do we need Task.ContinueWith()
method. Cannot we just write that "continuation code" inside Task body?
Sometimes you receive a Task from the outside and want to chain your continuation to it. There are also ways to create a task without an Action (e.g. using TaskCompletionSource).
Sasha Goldshtein's answer is correct. There are instances where your 'continue' composition code does not have direct access to, or even set the execution method of a task. A pluggable system that wants to aggregate taks, for example.
However, there is another reason that may apply. Granularity
Consider the requirements that may provoke use of TaskCreationOptions.LongRunning. In a parallel system where many hundreds of processes are being scheduled, executed and completed, the task scheduler is working to promote efficient processor affinity when scheduling tasks.
If you are in a situation where you can break down a task into fine-grained sub tasks and chain them, you will no longer need to use TaskCreationOptions.LongRunning. In simple terms, this will perform better because it is easier to schedules 100 small tasks to finish at the same time, than it is to schedule 10 large tasks to do the same in an environment where only 4 cores are available. Remember that a chained task is not guaranteed to start immediately after it's antecedent.
It is an interesting question and one that only becomes an issue when you want a scalable system.
If you ask me, you should use ContinueWith() where possible as it will help your app scale.
Sometimes you receive a Task from the outside and want to chain your continuation to it. There are also ways to create a task without an Action (e.g. using TaskCompletionSource).
Task continuations allow you to chains of Tasks, each Task in the chain is followed by one other Task
Also in Task.ContinueWith
method you can asynchronously check the Task
with TaskContinuationOptions
when the target Task
completes or an error occurs
Task task = Task.Factory.StartNew
(
() =>
{
//Your action when the task started
}
);
task.ContinueWith
(
_ =>
{
//Your action when the task completed
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent,
TaskScheduler.FromCurrentSynchronizationContext()
);
task.ContinueWith
(
(t) =>
{
//Action when error occured
Exception exception = null;
if (t.Exception.InnerException != null)
{
exception = t.Exception.InnerException;
}
else
{
exception = t.Exception;
}
//You can use this exception
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent,
TaskScheduler.FromCurrentSynchronizationContext()
);
For more information look here
© 2022 - 2024 — McMap. All rights reserved.