Мы продолжаем погружаться в работу с задачами. Следующий шаг - это отмена и правильная обработка состояния отмены. Ответственность за отмену задач лежит на разработчике.
В парадигме Structured Concurrency мы постоянно переключаемся между состояниями. Поэтому если задача была отменена, то было бы хорошо прекратить её дальнейшее исполнение.
let hardTask = Task { ... }
// Отменим задачу через 3 секунды
Task {
try await Task.sleep(nanoseconds: 3_000_000_000)
task.cancel()
}
Есть два основных способа проверить отменена ли задача
let hardTask = Task {
for step in 0...10 {
/// Проверяем не отменена ли задача
guard !Task.isCancelled else {
print("Task was cancelled")
return
}
print("Выполнение шага - \\(step)"
try await Task.sleep(nanoseconds: 1_000_000_000) // Имитация нагрузки
}
}
// Отменим задачу через 3 секунды
Task {
try await Task.sleep(nanoseconds: 3_000_000_000)
task.cancel()
}
В примере выше видно, что мы выполним не больше 4х шагов, благодаря такой проверке мы не выполняем остальные 6 шагов, тем самым разгружая исполнитель от ненужной работы.
Писать постоянно проверку в задачах - плохо, потому что это делает ваш код нечитабельным. Приведём несколько советов:
let imageTask = Task {
let imageInfo = fetchImageInfo()
let image = await network.fetchImage(with: imageInfo.id)
let croppedImages = await cropService.crop(image: image)
guard !Task.isCancelled else {
await imageService.removeImage(with: imageInfo)
return
}
await MainActor.run {
state.croppedImages = croppedImages
}
}