Полное руководство по языку программирования С# 14 и платформе .NET 10 / Параллельное программирование и библиотека TPL

Задачи продолжения

Начальный ⏱ 2 мин чтения 👁 2 🕓 обновлено 11.08.2026

Задачи продолжения или continuation task позволяют определить задачи, которые выполняются после завершения других задач. Благодаря этому мы можем вызвать после выполнения одной задачи несколько других, определить условия их вызова, передать из предыдущей задачи в следующую некоторые данные.

Задачи продолжения похожи на методы обратного вызова, но фактически являются обычными задачами Task. Посмотрим на примере:


Task task1 = new Task(() =>
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
});

// задача продолжения - task2 выполняется после task1
Task task2 = task1.ContinueWith(PrintTask);

task1.Start();

// ждем окончания второй задачи
task2.Wait();
Console.WriteLine("Конец метода Main");

 
void PrintTask(Task t)
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
    Console.WriteLine($"Id предыдущей задачи: {t.Id}");
    Thread.Sleep(3000);
}

Первая задача задается с помощью лямбда-выражения, которое просто выводит id этой задачи. Вторая задача - задача продолжения задается с помощью метода ContinueWith, который в качестве параметра принимает делегат Action<Task>. То есть метод PrintTask, который передается в вызов ContinueWith, должен принимать параметр типа Task.

Благодаря передачи в метод параметра Task, мы можем получить различные свойства предыдущей задачи, как например, в данном случае получает ее Id.

И после завершения задачи task1 сразу будет вызываться задача task2. Консольный вывод программы:

Id задачи: 1
Id задачи: 2
Id предыдущей задачи: 1
Конец метода Main

Также мы можем передавать конкретный результат работы предыдущей задачи:


Task<int> sumTask = new Task<int>(() => Sum(4, 5));

// задача продолжения
Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

sumTask.Start();

// ждем окончания второй задачи
printTask.Wait();
Console.WriteLine("Конец метода Main");

int Sum(int a, int b) => a + b;
void PrintResult(int sum) => Console.WriteLine($"Sum: {sum}");

В данном случае задача sumTask выполняет метод Sum и возвращает его результат. Задача printTask является задачей продолжения, выполняется сразу после sumTask и получает ее результат. Так, в вызове

Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

Параметр task в лямбда-выражении фактически представляет задачу sumTask, из которой извлекается результат.

Подобным образом можно построить целую цепочку последовательно выполняющихся задач:


Task task1 = new Task(() => Console.WriteLine($"Current Task: {Task.CurrentId}"));

// задача продолжения
Task task2 = task1.ContinueWith(t =>
    Console.WriteLine($"Current Task: {Task.CurrentId}  Previous Task: {t.Id}"));

Task task3 = task2.ContinueWith(t =>
    Console.WriteLine($"Current Task: {Task.CurrentId}  Previous Task: {t.Id}"));


Task task4 = task3.ContinueWith(t =>
    Console.WriteLine($"Current Task: {Task.CurrentId}  Previous Task: {t.Id}"));

task1.Start();

task4.Wait();   //  ждем завершения последней задачи
Console.WriteLine("Конец метода Main");

здесь друг за другом выполняются задачи task1, task2, task3, task4. Консольный вывод программы:

Current Task: 1
Current Task: 2  Previous Task: 1
Current Task: 3  Previous Task: 2
Current Task: 4  Previous Task: 3
Конец метода Main

Проверь себя

📋 Тест по теме «Задачи продолжения» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

_____ task1 = new Task(() =>
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
});

// задача продолжения - task2 выполняется после task1
Task task2 = task1.ContinueWith(PrintTask);

task1.Start();

// ждем окончания второй задачи
task2.Wait();
Console.WriteLine("Конец метода Main");

 
void PrintTask(Task t)
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
    Console.WriteLine($"Id предыдущей задачи: {t.Id}");
    Thread.Sleep(3000);
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Task<int> _____ = new Task<int>(() => Sum(4, 5));

// задача продолжения
Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

sumTask.Start();

// ждем окончания второй задачи
printTask.Wait();
Console.WriteLine("Конец метода Main");

int Sum(int a, int b) => a + b;
void PrintResult(int sum) => Console.WriteLine($"Sum: {sum}");
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Task printTask = _____.ContinueWith(task => PrintResult(task.Result));
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

_____ task1 = new Task(() => Console.WriteLine($"Current Task: {Task.CurrentId}"));

// задача продолжения
Task task2 = task1.ContinueWith(t =>
    Console.WriteLine($"Current Task: {Task.CurrentId}  Previous Task: {t.Id}"));

Task task3 = task2.ContinueWith(t =>
    Console.WriteLine($"Current Task: {Task.CurrentId}  Previous Task: {t.Id}"));


Task task4 = task3.ContinueWith(t =>
    Console.WriteLine($"Current Task: {Task.CurrentId}  Previous Task: {t.Id}"));

task1.Start();

task4.Wait();   //  ждем завершения последней задачи
Console.WriteLine("Конец метода Main");
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Task task1 = new Task(() =>
{
    Console.WriteLine($"Id задачи: {Task._____}");
});

// задача продолжения - task2 выполняется после task1
Task task2 = task1.ContinueWith(PrintTask);

task1.Start();

// ждем окончания второй задачи
task2.Wait();
Console.WriteLine("Конец метода Main");

 
void PrintTask(Task t)
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
    Console.WriteLine($"Id предыдущей задачи: {t.Id}");
    Thread.Sleep(3000);
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

_____ task1 = new Task(() =>
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
});

// задача продолжения - _____ выполняется после task1
Task task2 = task1.ContinueWith(PrintTask);

task1.Start();

// ждем окончания второй задачи
task2.Wait();
Console.WriteLine("Конец метода Main");

 
void PrintTask(Task t)
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
    Console.WriteLine($"Id предыдущей задачи: {t.Id}");
    Thread.Sleep(3000);
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

Task<int> _____ = new Task<int>(() => _____(4, 5));

// задача продолжения
Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

sumTask.Start();

// ждем окончания второй задачи
printTask.Wait();
Console.WriteLine("Конец метода Main");

int Sum(int a, int b) => a + b;
void PrintResult(int sum) => Console.WriteLine($"Sum: {sum}");
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Задачи продолжения»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Задачи продолжения», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

Task task1 = new Task(() =>
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
});

// задача продолжения - task2 выполняется после task1
Task task2 = task1.ContinueWith(PrintTask);

task1.Start();

// ждем окончания второй задачи
task2.Wait();
Console.WriteLine("Конец метода Main");

 
void PrintTask(Task t)
{
    Console.WriteLine($"Id задачи: {Task.CurrentId}");
    Console.WriteLine($"Id предыдущей задачи: {t.Id}");
    Thread.Sleep(3000);
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Задачи продолжения»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

Task<int> sumTask = new Task<int>(() => Sum(4, 5));

// задача продолжения
Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

sumTask.Start();

// ждем окончания второй задачи
printTask.Wait();
Console.WriteLine("Конец метода Main");

int Sum(int a, int b) => a + b;
void PrintResult(int sum) => Console.WriteLine($"Sum: {sum}");
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Задачи продолжения»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Задачи продолжения»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Задачи продолжения». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.