Почему Continue с передачей Задачи в качестве параметра
У меня есть Task<T> t1
, Я хочу запустить другой Task t2
после t1
завершается. Я решил использовать .ContinueWith
метод t1
,
void ThenFrob(Task<Frobber> t1) {
t1.ContinueWith(frobber => frobber.Frob())
}
За исключением того, что я не могу сделать это, потому что параметр Action Task<T>
передан Task<T>
, скорее, чем T
сам. Вместо этого я должен взять результат параметра, переданного в мое действие, чтобы взаимодействовать с ним.
void ThenFrob(Task<Frobber> t1) {
t1.ContinueWith(frobberTask => {
var frobber = frobberTask.Result;
frobber.frob();
});
}
Если цель ContinueWith - добавить еще одно действие в цепочку, почему бы разработчикам языков просто не передать результат предыдущего задания? Или в случае неуниверсального Задачи ожидается действие без параметров?
1 ответ
ContinueWith запускает делегат, когда задача входит в task.IsCompleted == true
государство. Не когда он входит в task.IsCompleted == true && task.IsFaulted == false && task.IsCanceled == false
состояние, задача, которая вызвала исключение или задача, которая была отменена, оба "завершены", но не приведут к результату.
Есть перегрузки, которые вы можете передать TaskContinuationOptions
лайк TaskContinuationOptions.OnlyOnRanToCompletion
чтобы получить поведение, как вы описываете, но было бы сложнее иметь Action<T>
перегрузка только для этого единственного параметра перечисления, чтобы они просто используют общую перегрузку Action<Task<T>>
так что вы можете использовать тот же метод, если вы делаете OnlyOnRanToCompletion
или если вы делаете OnlyOnFaulted
,
Также есть еще полезная информация в Task
объект выполненного задания, если вы используете AsyncState
свойство передавать метаданные, если выполненная задача не была передана ContinueWith
у вас не было бы способа получить эти данные, если бы вы не использовали захват переменных лямбад-выражения.