task: Выполнение Future и освобождение ресурсов
Описывает однократное использование, выполнение и отмену асинхронных операций после очистки.
Wave Foundation
Базовый API
Импортировано как import("std::task" as task);.
block_on<T>(future: Future<T>) -> T
spawn<T>(future: Future<T>) -> Future<T>
cancel<T>(future: Future<T>) -> bool
yield_now() -> Future<void>
sleep_ms(milliseconds: i64) -> Future<void>
cancel_and_join<T>(future: Future<T>) -> Future<void>
shutdown()
task::block_on(pending) выполняется до тех пор, пока Future не завершится и не вернет результат. Тип результата определяется из переданного Future.
правила жизни
Future — это дескриптор одноразового потребления. Я не рассматриваю копирование значений как две независимые операции. Вы также несете ответственность за ожидание результатов или отмену/организацию задач, запланированных с помощью spawn. Future уже использован с await и block_on не будет использован снова.
отменить запросы на отмену; сам по себе он не гарантирует завершения очистки. Дождитесь требуемого завершения, прежде чем освобождать ресурсы. Не освобождайте память, занятую асинхронным вводом-выводом, пока задача еще может получить к ней доступ. Вызовите shutdown после завершения задач или завершения очистки при отмене.
совместное исполнение
Длительные вычисления и синхронные вызовы blocking могут замедлить общий прогресс исполнителя. Асинхронное ожидание с yield дает возможность выполнения. Блокировка I/O не становится асинхронной только потому, что она находится внутри функции async.
Посмотрите последовательность выполнения и очистки в полной программе в Введение в асинхронный код.
Уступить и дождаться завершения
Следующая программа завершает выполнение в середине операции и возвращает результат. Поскольку yield не является завершением функции, код после await выполняется непрерывно.
import("std::task" as task);
async fun calculate() -> i32 {
println("started");
await task::yield_now();
println("resumed");
return 42;
}
fun main() -> i32 {
var pending: Future<i32> = calculate();
var result: i32 = task::block_on(pending);
println("result={}", result);
task::shutdown();
return 0;
}
Результат выполнения:
started
resumed
result=42
В этом примере нет других операций, поэтому порядок вывода одинаков. В программе, имеющей несколько задач spawn, другие задачи могут выполняться в точке yield, поэтому это не зависит от порядка вывода различных задач.
Порядок организации задач
- Подготовьте место для хранения и ресурсы, необходимые для работы.
- Создайте Future и запустите его как await, block_on или spawn.
- Если вам нужны результаты, дождитесь завершения.
- Если вы отменили выполняемую задачу, подождите, пока она очистится.
- Очищает буферы, файлы и сокеты, заимствованные задачей.
- Если работы не осталось, позвоните по номеру shutdown.
Future Выход из области действия переменной — это одно, а безопасная очистка работы — это другое. В частности, если вы передаете задаче адрес локального массива функции async, задача должна завершить использование этого массива до того, как функция вернется.
async Функции разделения и общие функции
Чистые вычисления можно разделить на обычные функции. Присоедините async к функции, которая должна выражать ожидание, и дождитесь завершения с помощью await внутри этой функции. Простое обертывание синхронной функции, которая занимает много времени, например, чтение файла, с помощью функции async не дает возможности выполнить другие задачи.
Вы можете сравнить создание и запуск Future с асинхронное обучение.