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::exception_services::exception_dispatch_info exception;
451 const xtd::any_object* state = &empty_state;
452 xtd::threading::auto_reset_event start_event;
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:69
static auto start_new() noexcept -> xtd::diagnostics::stopwatch
Initializes a new xtd::diagnostics::stopwatch instance, sets the xtd::diagnostics::stopwatch::elapsed...
static auto capture() -> exception_dispatch_info
Creates an xtd::exception_services::exception_dispatch_info object that represents the specified exce...
Definition exception_dispatch_info.hpp:70
static auto throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current()) -> void
Throws an exption with specified exception case.
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::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:60
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.
virtual auto sync_root() const noexcept -> const xtd::object &=0
Gets an object that can be used to synchronize access to the the xtd::collections::generic::icollecti...
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.