Почему 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 у вас не было бы способа получить эти данные, если бы вы не использовали захват переменных лямбад-выражения.

Другие вопросы по тегам