mirror of
https://github.com/izzy2lost/vba10.git
synced 2026-03-26 18:15:30 -07:00
106 lines
4.4 KiB
C++
106 lines
4.4 KiB
C++
#pragma once
|
|
|
|
#include <ppltasks.h>
|
|
#include <agents.h>
|
|
#include <memory>
|
|
#include <chrono>
|
|
|
|
namespace Concurrency
|
|
{
|
|
namespace extras
|
|
{
|
|
namespace details
|
|
{
|
|
static void iterative_task_impl(concurrency::task_completion_event<void> finished, std::function<concurrency::task<bool>()> body, concurrency::cancellation_token ct)
|
|
{
|
|
body().then([=] (concurrency::task<bool> previous) {
|
|
try {
|
|
if (previous.get())
|
|
iterative_task_impl(finished, body, ct);
|
|
else
|
|
finished.set();
|
|
} catch (...) {
|
|
finished.set_exception(std::current_exception());
|
|
}
|
|
}, ct);
|
|
}
|
|
} // namespace details
|
|
|
|
|
|
/// <summary>
|
|
/// Creates a task from given user Functor, which will be scheduled after <paramref name="delay"/> million senconds.
|
|
/// </summary>
|
|
/// <typeparam name="Func">
|
|
/// The type of the user task Functor.
|
|
/// </typeparam>
|
|
/// <param name="delay">
|
|
/// The delay before starting the task.
|
|
/// </param>
|
|
/// <param name="func">
|
|
/// The user task Functor.
|
|
/// </param>
|
|
/// <param name="token">
|
|
/// The optional cancellation token, which will be passed to the return task.
|
|
/// </param>
|
|
/// <returns>
|
|
/// It will return a task constructed with user Functor <paramref name="func"/>, and cancellation token <paramref name="token"/>.
|
|
/// The returning task will be scheduled after <paramref name="delay"/> million seconds.
|
|
/// </returns>
|
|
/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
|
|
/**/
|
|
template <typename Func>
|
|
auto create_delayed_task(std::chrono::milliseconds delay, Func func, concurrency::cancellation_token token = concurrency::cancellation_token::none()) -> decltype(create_task(func))
|
|
{
|
|
concurrency::task_completion_event<void> tce;
|
|
|
|
auto pTimer = new concurrency::timer<int>(static_cast<int>(delay.count()), 0, NULL, false);
|
|
auto pCallback = new concurrency::call<int>([tce](int) {
|
|
tce.set();
|
|
});
|
|
|
|
pTimer->link_target(pCallback);
|
|
pTimer->start();
|
|
|
|
return create_task(tce).then([pCallback, pTimer]() {
|
|
delete pCallback;
|
|
delete pTimer;
|
|
}).then(func, token);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a task iteratively execute user Functor. During the process, each new iteration will be the continuation of the
|
|
/// last iteration's returning task, and the process will keep going on until the Boolean value from returning task becomes False.
|
|
/// </summary>
|
|
/// <param name="body">
|
|
/// The user Functor used as loop body. It is required to return a task with type bool, which used as predictor that decides
|
|
/// whether the loop needs to be continued.
|
|
/// </param>
|
|
/// <param name="ct">
|
|
/// The cancellation token linked to the iterative task.
|
|
/// </param>
|
|
/// <returns>
|
|
/// The task that will perform the asynchronous iterative execution.
|
|
/// </returns>
|
|
/// <remarks>
|
|
/// This function dynamically creates a long chain of continuations by iteratively concating tasks created by user Functor <paramref name="body"/>,
|
|
/// The iteration will not stop until the result of the returning task from user Functor <paramref name="body"/> is <c> False </c>.
|
|
/// </remarks>
|
|
/// <seealso cref="Task Parallelism (Concurrency Runtime)"/>
|
|
/**/
|
|
inline task<void> create_iterative_task(std::function<concurrency::task<bool>()> body, cancellation_token ct = cancellation_token::none())
|
|
{
|
|
concurrency::task_completion_event<void> finished;
|
|
create_task([=] {
|
|
try {
|
|
details::iterative_task_impl(finished, body, ct);
|
|
} catch (...) {
|
|
finished.set_exception(std::current_exception());
|
|
}
|
|
}, ct);
|
|
return create_task(finished, ct);
|
|
}
|
|
|
|
}
|
|
}
|
|
|