Зачем нам нужен метод Task.ContinueWith()
. Не можем ли мы просто написать этот "код продолжения" внутри тела задачи?
Зачем нам нужен метод ContinueWith?
Ответ 1
Иногда вы получаете задание извне и хотите связать свое продолжение с ним. Существуют также способы создания задачи без действия (например, с использованием объекта TaskCompletionSource).
Ответ 2
Ответ Саши Голдштейн правильный. Существуют случаи, когда ваш код композиции "continue" не имеет прямого доступа или даже задает способ выполнения задачи. Например, подключаемая система, которая хочет, например, агрегировать taks.
Однако есть и другая причина, которая может применяться. Зернистость
Учитывайте требования, которые могут спровоцировать использование TaskCreationOptions.LongRunning. В параллельной системе, где запланировано, выполнено и завершено много сотен процессов, планировщик задач работает для повышения эффективности работы процессора при планировании задач.
Если вы находитесь в ситуации, когда вы можете разбить задачу на мелкие суб-задачи и связать их, вам больше не понадобится использовать TaskCreationOptions.LongRunning, Проще говоря, это будет работать лучше, потому что легче планировать 100 небольших задач, чтобы закончить в одно и то же время, чем планировать 10 больших задач, чтобы сделать то же самое в среде, где доступно только 4 ядра. Помните, что целенаправленная задача не гарантируется сразу же после антецедента.
Это интересный вопрос, который становится проблемой, когда вы хотите масштабируемую систему.
Если вы спросите меня, вы должны использовать ContinueWith(), где это возможно, так как это поможет вашему шкале приложений.
Ответ 3
Продолжение задач позволяет вам цепочки Заданий, каждая Задача в цепочке сопровождается еще одной Задачей
Также в методе Task.ContinueWith
вы можете асинхронно проверять Task
на TaskContinuationOptions
, когда цель Task
завершается или происходит ошибка
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()
);
Для получения дополнительной информации смотрите здесь