Ответ
Да, Task можно отменить, используя механизм CancellationToken.
Основной подход:
- Создайте
CancellationTokenSource. - Передайте
cancellationTokenв задачу. - Задача должна периодически проверять статус отмены.
- Вызовите
cancel()для инициации отмены.
Пример создания и отмены задачи:
let tokenSource = CancellationTokenSource()
let task = Task {
// Периодически проверяем отмену
for i in 1...10 {
try Task.checkCancellation() // Выбрасывает CancellationError при отмене
print("Processing item (i)")
try await Task.sleep(nanoseconds: 1_000_000_000)
}
}
// Через 3 секунды отменяем задачу
Task {
try await Task.sleep(nanoseconds: 3_000_000_000)
tokenSource.cancel()
print("Task cancellation requested")
}
Ключевые моменты:
- Отмена кооперативная — задача должна явно проверять
Task.isCancelledили вызыватьTask.checkCancellation(). - Состояние задачи — после отмены
task.isCancelledбудетtrue, ноtask.isCompletedстанетtrueтолько после завершения работы задачи. - Очистка ресурсов — используйте
deferилиTask.checkCancellation()для корректного освобождения ресурсов при отмене.
Проверка отмены вручную:
Task {
while !Task.isCancelled {
// Выполняем работу
await processNextItem()
}
// Выполняем финализацию
cleanupResources()
}