Мне интересно, какова цель .then конструкции в PPL и где я могу это проверить? Кажется, Visual Studio 2012 пока не поддерживает его (может быть, некоторые будущие CTP?). И есть ли у него эквиваленты в стандартной асинхронной библиотеке C ++ 11?
Цель состоит в том, чтобы вы могли выражать асинхронные задачи, которые должны выполняться последовательно.
Например, скажем, я нахожусь в приложении с графическим интерфейсом. Когда пользователь нажимает кнопку, я хочу асинхронно запустить задачу для извлечения файла в оперативном режиме, затем обработать его для получения каких-либо данных, а затем использовать эти данные для обновления графического интерфейса. В то время как это происходит, есть множество других задач, в основном, чтобы обеспечить отзывчивость GUI.
Это может быть сделано с помощью обратных вызовов, которые вызывают обратные вызовы.
Функция .then (), связанная с лямбдами, позволяет вам записывать весь контент обратных вызовов, в котором вы его создаете (вы можете использовать отдельные обратные вызовы, если хотите).
Это также не гарантирует, что работа каждой отдельной задачи будет выполняться одним и тем же потоком, что позволяет свободным потокам красть задачи, если исходный поток уже выполняет слишком много работы.
Функция .then () не существует в C ++ 11, но ее предлагается добавить в класс std :: future (который в основном является дескриптором задачи или результата задачи).
Клаим уже сделал отличный ответ, но я подумал, что приведу конкретный пример.
.then
присоединяет продолжение к задаче и является асинхронным эквивалентом синхронного .get
, в принципе.
C ++ 11 имеет std::future
, что эквивалентно concurrency::task
, std::future
в настоящее время имеет только .get
, но есть предложение добавить .then
(и другие хорошие вещи).
std::async(calculate_answer(the_question_of_everything))
.then([](std::future<int> f){ std::cout << f.get() << "\n"; });
Приведенный выше фрагмент создаст асинхронную задачу (запускается с std::async
), а затем прикрепите продолжение, которое проходит std::future
законченного задания, как только вышеупомянутое задание выполнено. Это на самом деле возвращает другой std::future
за тот задача, и текущий стандарт C ++ 11 будет блокировать его деструктор, но есть еще одно предложение, чтобы разблокировать деструктор. Таким образом, с помощью приведенного выше кода вы создаете задачу «забей и забудь», которая печатает ответ сразу после его вычисления.
Эквивалент блокировки будет:
auto f = std::async(calculate_answer(the_question_of_everything));
std::cout << f.get() << "\n";
Этот код заблокирует в f.get()
пока ответ не станет доступным.