33 template<
class result_t =
void>
36 template<
class result_t>
48 template<
class result_t =
void>
49 class basic_task :
public itask,
public xtd::iasync_result {
68 data_->cancellation_token = cancellation_token;
71 data_->parameterized_func =
func;
72 data_->state = &state;
74 basic_task(
const xtd::func<result_t>&
func,
const xtd::any_object& state,
const xtd::threading::cancellation_token& cancellation_token) {
76 data_->state = &state;
77 data_->cancellation_token = cancellation_token;
82 basic_task(
const std::function<
void()>&
func) {
85 basic_task(
const std::function<
void()>&
func,
const xtd::threading::cancellation_token& cancellation_token) {
87 data_->cancellation_token = cancellation_token;
89 basic_task(
const std::function<
void(
const xtd::any_object&)>&
func,
const xtd::any_object& state) {
90 data_->parameterized_func =
func;
91 data_->state = &state;
93 basic_task(
const std::function<
void(
const xtd::any_object&)>&
func,
const xtd::any_object& state,
const xtd::threading::cancellation_token& cancellation_token) {
94 data_->parameterized_func =
func;
95 data_->state = &state;
96 data_->cancellation_token = cancellation_token;
99 template<
class create_result_t>
100 basic_task(
const std::function<create_result_t()>&
func) {
103 template<
class create_result_t>
104 basic_task(
const std::function<create_result_t()>&
func,
const xtd::threading::cancellation_token& cancellation_token) {
106 data_->cancellation_token = cancellation_token;
108 template<
class create_result_t>
109 basic_task(
const std::function<create_result_t(
const xtd::any_object&)>&
func,
const xtd::any_object& state) {
110 data_->parameterized_func =
func;
111 data_->state = &state;
113 template<
class create_result_t>
114 basic_task(
const std::function<create_result_t(
const xtd::any_object&)>&
func,
const xtd::any_object& state,
const xtd::threading::cancellation_token& cancellation_token) {
115 data_->parameterized_func =
func;
116 data_->state = &state;
117 data_->cancellation_token = cancellation_token;
125 [[nodiscard]]
auto async_state() const noexcept -> xtd::any_object
override {
return data_->async_state;}
126 [[nodiscard]]
auto creation_options() const noexcept -> xtd::threading::tasks::
task_creation_options {
return data_->creation_options;}
132 [[nodiscard]]
auto id() const noexcept -> xtd::
size override {
return data_->id;}
136 [[nodiscard]]
auto status() const noexcept -> xtd::threading::tasks::
task_status {
return data_->status;}
142 [[nodiscard]]
static auto completed_task() -> task<result_t>;
143 [[nodiscard]]
static auto current_id() noexcept -> xtd::
size {
return current_id_;}
144 [[nodiscard]]
static auto factory() noexcept -> const xtd::threading::tasks::task_factory&;
150 auto continue_with(std::function<
void()> continuation) ->
void {continue_with(
xtd::action<> {continuation});}
152 auto call_now =
false;
154 lock_(data_->sync_root) {
155 if (is_completed()) call_now =
true;
156 else data_->continuation = continuation;
159 if (call_now) continuation();
162 [[noreturn]]
auto rethrow_exception() ->
void {
163 if (is_faulted () && data_->exception)
throw *data_->exception.source_exception();
167 auto run_synchronously() ->
void {
169 data_->task_proc(data_->state,
false);
174 auto start() ->
void override {
179 data_->start_event.set();
187 auto wait(
xtd::int32 milliseconds_timeout) ->
bool override {
188 auto cancellation_token = xtd::threading::cancellation_token {};
189 return wait(milliseconds_timeout, cancellation_token);
194 auto wait(
xtd::int32 milliseconds_timeout, xtd::threading::cancellation_token& cancellation_token) ->
bool override {
195 auto& cancellation_token_wait_handle = cancellation_token.wait_handle();
203 auto wait(
const xtd::time_span& timeout) ->
bool override {
return wait(
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()));}
207 auto wait(
const xtd::time_span& timeout, xtd::threading::cancellation_token& cancellation_token) ->
bool override {
return wait(
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()), cancellation_token);}
213 [[nodiscard]]
static auto from_cancelation(
const xtd::threading::cancellation_token& cancellation_token) -> task<result_t>;
215 template<
class from_exception_t>
216 [[nodiscard]]
static auto from_exception(from_exception_t exception) -> task<result_t>;
218 [[nodiscard]]
static auto delay(
const xtd::time_span& delay) -> task<>;
219 [[nodiscard]]
static auto delay(
const xtd::time_span& delay,
const xtd::threading::cancellation_token& cancellation_token) -> task<>;
220 [[nodiscard]]
static auto delay(
xtd::int32 milliseconds_delay) -> task<>;
221 [[nodiscard]]
static auto delay(
xtd::int32 milliseconds_delay,
const xtd::threading::cancellation_token& cancellation_token) -> task<>;
224 [[nodiscard]]
static auto run(
const xtd::func<result_t>&
func,
const xtd::threading::cancellation_token& cancellation_token) -> task<result_t>;
228 template<
class collection_t>
231 template<
class collection_t>
232 static auto wait_all(
const collection_t& tasks,
xtd::int32 milliseconds_timeout) ->
bool {
233 auto task_pointers = std::vector<itask*> {};
234 for (
auto& task : tasks)
235 task_pointers.push_back(
const_cast<decltype(&task)
>(&task));
236 return wait_all(array<itask*> {task_pointers}, milliseconds_timeout);
239 template<
class collection_t>
240 static auto wait_all(
const collection_t& tasks,
const xtd::time_span& timeout) ->
bool {
return wait_all(tasks,
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()));}
242 template<
class collection_t>
243 static size_t wait_any(
const collection_t& tasks) {
return wait_any(tasks,
timeout::infinite);}
245 template<
class collection_t>
246 static size_t wait_any(
const collection_t& tasks,
int32 milliseconds_timeout) {
247 auto task_pointers = std::vector<itask*> {};
248 for (
auto& task : tasks)
249 task_pointers.push_back(
const_cast<decltype(&task)
>(&task));
250 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
253 template<
class collection_t>
254 static size_t wait_any(
const collection_t& tasks,
const time_span& timeout) {
return wait_any(tasks,
as<int32>(timeout.total_milliseconds_duration().count()));}
258 [[nodiscard]]
static auto run(
const std::function<result_t()>&
func) -> task<result_t>;
259 [[nodiscard]]
static auto run(
const std::function<result_t()>&
func,
const xtd::threading::cancellation_token& cancellation_token) -> task<result_t>;
260 [[nodiscard]]
static auto run(
const std::function<result_t(
const xtd::any_object&)>&
func,
const xtd::any_object& state) -> task<result_t>;
261 [[nodiscard]]
static auto run(
const std::function<result_t(
const xtd::any_object&)>&
func,
const xtd::any_object& state,
const xtd::threading::cancellation_token& cancellation_token) -> task<result_t>;
263 template<
class ...items_t>
265 template<
class ...items_t>
266 static auto wait_all(
const xtd::time_span& timeout, items_t... items) ->
bool {
return wait_all(
xtd::as<xtd::int32>(timeout.total_milliseconds()), items...);}
267 template<
class ...items_t>
268 static auto wait_all(
xtd::int32 milliseconds_timeout, items_t... items) ->
bool {
269 auto task_pointers = std::vector<itask*> {};
270 fill_task_pointers(task_pointers, items...);
271 return wait_all(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
273 template<
class item_t>
274 static auto wait_all(
const std::initializer_list<item_t>& tasks) ->
bool {
return wait_all(tasks,
timeout::infinite);}
275 template<
class item_t>
276 static auto wait_all(
const std::initializer_list<item_t>& tasks,
xtd::int32 milliseconds_timeout) ->
bool {
277 auto task_pointers = std::vector<itask*> {};
278 for (
auto& task : tasks)
279 task_pointers.push_back(
const_cast<item_t*
>(&task));
280 return wait_all(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
282 template<
class item_t>
283 static auto wait_all(
const std::initializer_list<item_t>& tasks,
const xtd::time_span& timeout) ->
bool {
return wait_all(tasks,
as<int32>(timeout.total_milliseconds_duration().count()));}
286 auto task_pointers = std::vector<itask*> {};
287 for (
auto& task : tasks)
288 task_pointers.push_back(task.get());
289 return wait_all(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
291 static auto wait_all(
const std::initializer_list<
xtd::sptr<itask>>& tasks,
const xtd::time_span& timeout) ->
bool {
return wait_all(tasks,
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()));}
294 auto task_pointers = std::vector<itask*> {};
295 for (
auto& task : tasks)
296 task_pointers.push_back(task.get());
297 return wait_all(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
299 static auto wait_all(
const std::initializer_list<
xtd::uptr<itask>>& tasks,
const xtd::time_span& timeout) ->
bool {
return wait_all(tasks,
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()));}
302 auto task_pointers = std::vector<itask*> {};
303 for (
auto& task : tasks)
304 task_pointers.push_back(task.get());
305 return wait_all(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
307 static auto wait_all(
const xtd::array<
xtd::sptr<itask>>& tasks,
const xtd::time_span& timeout) ->
bool {
return wait_all(tasks,
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()));}
310 auto task_pointers = std::vector<itask*> {};
311 for (
auto& task : tasks)
312 task_pointers.push_back(task.get());
313 return wait_all(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
315 static auto wait_all(
const xtd::array<
xtd::uptr<itask>>& tasks,
const xtd::time_span& timeout) ->
bool {
return wait_all(tasks,
xtd::as<xtd::int32>(timeout.total_milliseconds_duration().count()));}
316 static auto wait_all(
const xtd::array<itask*>& tasks,
xtd::int32 milliseconds_timeout) ->
bool {
320 for (
auto task : tasks)
326 for (
auto& task : tasks)
327 if (sw.elapsed_milliseconds() > milliseconds_timeout || task->wait(milliseconds_timeout -
xtd::as<xtd::int32>(sw.elapsed_milliseconds())))
return false;
331 template<
class ...items_t>
333 template<
class ...items_t>
334 static auto wait_any(
const xtd::time_span& timeout, items_t... items) ->
xtd::size {
return wait_any(
xtd::as<xtd::int32>(timeout.total_milliseconds()), items...);}
335 template<
class ...items_t>
337 auto task_pointers = std::vector<itask*> {};
338 fill_task_pointers(task_pointers, items...);
339 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
341 template<
class item_t>
343 template<
class item_t>
344 static auto wait_any(
const std::initializer_list<item_t>& tasks,
xtd::int32 milliseconds_timeout) ->
xtd::size {
345 auto task_pointers = std::vector<itask*> {};
346 for (
auto& task : tasks)
347 task_pointers.push_back(
const_cast<item_t*
>(&task));
348 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
350 template<
class item_t>
351 static auto wait_any(
const std::initializer_list<item_t>& tasks,
const xtd::time_span& timeout) ->
xtd::size {
return wait_any(tasks,
as<int32>(timeout.total_milliseconds_duration().count()));}
354 auto task_pointers = std::vector<itask*> {};
355 for (
auto& task : tasks)
356 task_pointers.push_back(task.get());
357 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
362 auto task_pointers = std::vector<itask*> {};
363 for (
auto& task : tasks)
364 task_pointers.push_back(task.get());
365 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
370 auto task_pointers = std::vector<itask*> {};
371 for (
auto& task : tasks)
372 task_pointers.push_back(task.get());
373 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
378 auto task_pointers = std::vector<itask*> {};
379 for (
auto& task : tasks)
380 task_pointers.push_back(task.get());
381 return wait_any(xtd::array<itask*> {task_pointers}, milliseconds_timeout);
384 static auto wait_any(
const xtd::array<itask*>& tasks,
xtd::int32 milliseconds_timeout) ->
xtd::size {
387 auto sleep_duration = 1;
388 const auto max_sleep = 10;
392 for (
auto index =
xtd::size {0}; index < tasks.length(); ++index)
393 if (tasks[index]->wait(0))
return index;
396 sleep_duration = std::min(sleep_duration + 1, max_sleep);
402 static auto yield() -> task<result_t>;
406 template<
class task_result_t>
408 template<
class batic_task_result_t>
409 friend class batic_task;
411 basic_task() =
default;
412 basic_task(basic_task&&) =
default;
413 basic_task(
const basic_task&) =
default;
414 auto operator=(basic_task&&) -> basic_task& =
default;
415 auto operator=(
const basic_task&) -> basic_task& =
default;
417 [[nodiscard]]
auto async_wait_handle() noexcept -> xtd::threading::wait_handle&
override {
return data_->async_event;}
418 [[nodiscard]]
auto completed_synchronously() const noexcept ->
bool override {
return false;}
420 template<
class item_t,
class ...items_t>
421 static auto fill_task_pointers(std::vector<itask*>& itask_pointer, item_t&
first, items_t& ... rest) ->
void {
422 itask_pointer.push_back(&
first);
423 fill_task_pointers(itask_pointer, rest...);
425 template<
class item_t>
426 static auto fill_task_pointers(std::vector<itask*>& itask_pointer, item_t& item) ->
void {
427 itask_pointer.push_back(&item);
430 static auto generate_id() noexcept -> xtd::
size {
436 using result_type = std::conditional_t<std::is_same_v<result_t, void>, std::uint8_t, result_t>;
439 xtd::threading::manual_reset_event async_event;
440 xtd::any_object async_state;
444 const xtd::any_object empty_state;
445 xtd::threading::auto_reset_event end_event;
446 xtd::runtime::exception_services::exception_dispatch_info exception;
451 const xtd::any_object* state = &empty_state;
452 xtd::threading::auto_reset_event start_event;
454 xtd::object sync_root;
457 auto previous_current_id = current_id_;
461 current_id_ = previous_current_id;
463 if (!continuation.is_empty()) continuation();
469 if constexpr(std::is_same_v<result_t, void>) {
471 else if (!parameterized_func.is_empty()) parameterized_func(state);
473 if (!
func.is_empty()) result =
func();
474 else if (!parameterized_func.is_empty()) result = parameterized_func(state);
478 }
catch (
const xtd::threading::tasks::task_canceled_exception& e) {
481 }
catch (
const xtd::exception& e) {
484 }
catch (
const std::exception& e) {
495 inline static thread_local xtd::size current_id_ = 0;
Contains xtd::action delegate.
Contains xtd::aggregate_exception exception.
Contains xtd::threading::auto_reset_event exception.
static constexpr size_t max_value
Definition box_integer.hpp:67
static auto start_new() noexcept -> xtd::diagnostics::stopwatch
Initializes a new xtd::diagnostics::stopwatch instance, sets the xtd::diagnostics::stopwatch::elapsed...
static auto throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current()) -> void
Throws an exption with specified exception case.
static auto capture() -> exception_dispatch_info
Creates an xtd::runtime::exception_services::exception_dispatch_info object that represents the speci...
Definition exception_dispatch_info.hpp:72
bool set()
Sets the state of the event to signaled, allowing one or more waiting threads to proceed.
Represents an interface for an asynchronous operation.
Definition itask.hpp:19
Provides support for creating and scheduling Task objects.
Definition task_factory.hpp:19
Represents an asynchronous operation.
Definition task_result.hpp:20
static registered_wait_handle register_wait_for_single_object(wait_handle &wait_object, const wait_or_timer_callback &callback, const xtd::any_object &state, int32 milliseconds_timeout_interval, bool execute_only_once)
Registers a delegate to wait for a xtd::threading::wait_handle, specifying a 32-bit signed integer fo...
static void sleep(int32 milliseconds_timeout)
Suspends the current thread for a specified time.
static constexpr int32 infinite
A constant used to specify an infinite waiting period. This field is constant.
Definition timeout.hpp:41
static size_t wait_any(const collection_t &wait_handles)
Waits for any of the elements in the specified collection to receive a signal.
Definition wait_handle.hpp:198
Contains xtd::runtime::exception_services::exception_dispatch_info class.
Contains xtd::func delegate.
xtd::delegate< result_t(arguments_t... arguments)> func
Represents a delegate that has variables parameters and returns a value of the type specified by the ...
Definition func.hpp:27
xtd::delegate< void(const xtd::any_object &state, bool timed_out)> wait_or_timer_callback
Represents a method to be called when a xtd::threading::wait_handle is signaled or times out.
Definition wait_or_timer_callback.hpp:30
xtd::delegate< void(async_result ar)> async_callback
References a method to be called when a corresponding asynchronous operation completes.
Definition delegate.hpp:39
@ argument
The argument is not valid.
Definition exception_case.hpp:31
@ task_canceled
The task is canceled.
Definition exception_case.hpp:103
@ invalid_operation
The operation is not valid.
Definition exception_case.hpp:65
#define scope_exit_
Nowadays, every C++ developer is familiar with the Resource Acquisition Is Initialization (RAII) tech...
Definition scope_exit.hpp:128
#define delegate_
The declaration of a delegate type is similar to a method signature. It has a return value and any nu...
Definition delegate.hpp:932
#define lock_(object)
The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion loc...
Definition lock.hpp:67
task_status
Represents the current stage in the lifecycle of a xtd::threading::tasks::task.
Definition task_status.hpp:23
task_creation_options
Specifies flags that control optional behavior for the creation and execution of tasks....
Definition task_creation_options.hpp:23
@ waiting_to_run
The task has been scheduled for execution but has not yet begun executing.
Definition task_status.hpp:29
@ running
The task is running but has not yet completed.
Definition task_status.hpp:31
@ ran_to_completion
The task completed execution successfully.
Definition task_status.hpp:35
@ waiting_for_activation
The task is waiting to be activated and scheduled internally by the Switch infrastructure.
Definition task_status.hpp:27
@ faulted
The task completed due to an unhandled exception.
Definition task_status.hpp:39
@ canceled
The task acknowledged cancellation by throwing an OperationCanceledException with its own Cancellatio...
Definition task_status.hpp:37
@ created
The task has been initialized but has not yet been scheduled.
Definition task_status.hpp:25
@ none
Specifies that the default behavior should be used.
Definition task_creation_options.hpp:25
bool yield() noexcept
Suggests that the implementation reschedule execution of threads.
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
xtd::shared_ptr_object< type_t > sptr
The xtd::sptr object is a shared pointer.
Definition sptr.hpp:25
null_ptr null
Represents a null pointer value.
xtd::unique_ptr_object< type_t > uptr
The xtd::uptr object is a unique pointer.
Definition uptr.hpp:25
std::int32_t int32
Represents a 32-bit signed integer.
Definition int32.hpp:23
xtd::reference_wrapper_object< type_t > ref
The xtd::ref object is a reference wrapper.
Definition ref.hpp:25
std::optional< type_t > optional
Represents the optional alias on std::optional.
Definition optional.hpp:26
auto as(any_object &o) -> type_t
Casts a type into another type.
Definition __as_any_object.hpp:59
auto as< xtd::int32 >(xtd::any value) -> xtd::int32
Casts a type into another type.
Definition __as_int32.hpp:36
delegate< void(arguments_t...)> action
Represents a xtd::delegate that has variable parameters and does not return a value.
Definition action.hpp:20
sptr< type_t > new_sptr(args_t &&... args)
xtd::new_sptr operator creates a xtd::sptr object.
Definition new_sptr.hpp:24
@ start
Starting of a logical operation.
Definition trace_event_type.hpp:37
@ e
The E key.
Definition console_key.hpp:96
Contains xtd::iasync_result interface.
Contains xtd::threading::tasks::itask interface.
The xtd::threading::tasks namespace provides types that simplify the work of writing concurrent and a...
Definition itask.hpp:14
The xtd::threading namespace provides classes and interfaces that enable multithreaded programming....
Definition abandoned_mutex_exception.hpp:10
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
read_only_span< type_t, count > first() const
Obtains a subspan consisting of the first count elements of the sequence.
Definition read_only_span.hpp:282
constexpr const_pointer data() const noexcept
Gets direct access to the underlying contiguous storage.
Definition read_only_span.hpp:201
Contains xtd::new_sptr method.
Contains xtd::optional type.
Contains scope_exit_ keyword.
Contains xtd::diagnostics::stopwatch class.
Contains xtd::threading::tasks::task_canceled_exception exception.
Contains xtd::threading::tasks::task_creation_options enum class.
Contains xtd::threading::tasks::task_status enum class.
Contains xtd::threading::thread_pool class.
Contains xtd::threading::lock class.
Contains xtd::helpers::throw_helper class.