xtd 1.0.0
Loading...
Searching...
No Matches
task_factory.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "task.hpp"
6
8namespace xtd {
10 namespace threading {
12 namespace tasks {
22 class task_factory : public xtd::object {
23 public:
25 task_factory() = default;
26 task_factory(task_factory&&) = default;
27 auto operator=(task_factory&&) -> task_factory& = default;
28 task_factory(const task_factory&) = default;
29 auto operator=(const task_factory&) -> task_factory& = default;
31
33
35 [[nodiscard]] auto continue_when_all(xtd::iterable auto&& tasks, auto&& action) const -> xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()())>> {
36 task<>::when_all(tasks).wait();;
38 t.start();
39 return t;
40 }
42 task<>::when_all(tasks).wait();;
44 t.start();
45 return t;
46 }
47 [[nodiscard]] auto continue_when_all(xtd::iterable auto&& tasks, auto&& action, const xtd::any_object& state) const -> xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {
48 task<>::when_all(tasks).wait();;
49 auto t = xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {action, state};
50 t.start();
51 return t;
52 }
53 template<typename result_t>
55 task<>::when_all(tasks).wait();;
56 auto t = xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {action, state, cancellation_token};
57 t.start();
58 return t;
59 }
60
61 [[nodiscard]] auto continue_when_any(xtd::iterable auto&& tasks, auto&& action) const -> xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()())>> {
62 task<>::when_any(tasks).wait();;
64 t.start();
65 return t;
66 }
68 task<>::when_any(tasks).wait();;
70 t.start();
71 return t;
72 }
73 [[nodiscard]] auto continue_when_any(xtd::iterable auto&& tasks, auto&& action, const xtd::any_object& state) const -> xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {
74 task<>::when_any(tasks).wait();;
75 auto t = xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {action, state};
76 t.start();
77 return t;
78 }
79 template<typename result_t>
81 task<>::when_any(tasks).wait();;
82 auto t = xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {action, state, cancellation_token};
83 t.start();
84 return t;
85 }
86
96
105
109 [[nodiscard]] auto start_new(auto&& action, const xtd::any_object& state) const -> xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {
110 auto t = xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {action, state};
111 t.start();
112 return t;
113 }
114
118 template<typename result_t>
120 auto t = xtd::threading::tasks::task<xtd::raw_type<decltype(std::declval<decltype(action)>()(std::declval<const xtd::any_object&>()))>> {action, state, cancellation_token};
121 t.start();
122 return t;
123 }
124
126 };
127
129 template<typename result_t>
130 struct xtd::threading::tasks::basic_task<result_t>::yield_awaiter {
132
133 yield_awaiter() {task_.start();};
134 bool await_ready() const noexcept {return task_.is_completed();}
135 void await_resume() {if (task_.is_faulted()) task_.rethrow_exception();}
136 void await_suspend(std::coroutine_handle<> handle) {task_.continue_with_([handle] {handle.resume();});}
137 };
138
139 template<typename result_t>
140 auto basic_task<result_t>::completed_task() -> xtd::threading::tasks::task<result_t> {
141 auto task = xtd::threading::tasks::task<result_t> {};
142 task.basic_task<result_t>::data_->status = xtd::threading::tasks::task_status::ran_to_completion;
143 task.basic_task<result_t>::data_->end_event.set();
144 return task;
145 }
146
147 template<typename result_t>
148 auto basic_task<result_t>::continue_with(xtd::action<>&& continuation) -> xtd::threading::tasks::task<> {
149 auto call_now = false;
150
151 lock_(data_->sync_root) {
152 data_->continuation = xtd::new_sptr<xtd::threading::tasks::task<>>(continuation);
153 if (is_completed()) call_now = true;
154 }
155
156 if (call_now) run_continuation(data_->continuation_async);
157 return *data_->continuation;
158 }
159
160 template<typename result_t>
161 auto basic_task<result_t>::continue_with(xtd::func<xtd::threading::tasks::task<>>&& continuation_async) -> xtd::threading::tasks::task<xtd::threading::tasks::task<>> {
162 auto call_now = false;
163
164 lock_(data_->sync_root) {
165 data_->continuation_async = xtd::new_sptr<xtd::threading::tasks::task<xtd::threading::tasks::task<>>>(continuation_async);
166 if (is_completed()) call_now = true;
167 }
168
169 if (call_now) run_continuation(data_->continuation_async);
170 return *data_->continuation_async;
171 }
172
173 template<typename result_t>
174 auto basic_task<result_t>::factory() noexcept -> const xtd::threading::tasks::task_factory& {
175 static auto factory = xtd::threading::tasks::task_factory {};
176 return factory;
177 }
178
179 template<typename result_t>
180 auto basic_task<result_t>::delay(const xtd::time_span& delay) -> xtd::threading::tasks::task<> {return basic_task<result_t>::delay(xtd::as<xtd::int32>(delay.total_milliseconds()));}
181
182 template<typename result_t>
183 auto basic_task<result_t>::delay(const xtd::time_span& delay, const xtd::threading::cancellation_token& cancellation_token) -> task<> {return basic_task<result_t>::delay(xtd::as<xtd::int32>(delay.total_milliseconds()), cancellation_token);}
184
185 template<typename result_t>
186 auto basic_task<result_t>::delay(xtd::int32 milliseconds_delay) -> xtd::threading::tasks::task<> {return xtd::threading::tasks::task<>::run([milliseconds_delay]{xtd::threading::cancellation_token {}.wait_handle().wait_one(milliseconds_delay);});}
187
188 template<typename result_t>
189 auto basic_task<result_t>::delay(xtd::int32 milliseconds_delay, const xtd::threading::cancellation_token& cancellation_token) -> task<> {
190 return xtd::threading::tasks::task<>::run([cancellation_token, milliseconds_delay]{xtd::threading::cancellation_token {cancellation_token}.wait_handle().wait_one(milliseconds_delay);}, cancellation_token);
191 }
192
193 template<typename result_t>
194 auto basic_task<result_t>::from_cancelation(const xtd::threading::cancellation_token& cancellation_token) -> task<result_t> {
195 if (!cancellation_token.is_cancellation_requested()) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_out_of_range);
196 auto task = xtd::threading::tasks::task<result_t> {};
197 task.basic_task<>::data_->cancellation_token = cancellation_token;
198 task.basic_task<>::data_->status = xtd::threading::tasks::task_status::canceled;
199 task.basic_task<>::data_->end_event.set();
200 return task;
201 }
202
203 template<typename result_t>
204 template<typename from_exception_t>
205 auto basic_task<result_t>::from_exception(from_exception_t exception) -> xtd::threading::tasks::task<result_t> {
206 auto task = xtd::threading::tasks::task<result_t> {};
207 task.basic_task<>::data_->exception = xtd::exception_services::exception_dispatch_info::capture(exception);
208 task.basic_task<>::data_->status = xtd::threading::tasks::task_status::faulted;
209 task.basic_task<>::data_->end_event.set();
210 return task;
211 }
212
213 template<typename result_t>
214 auto xtd::threading::tasks::basic_task<result_t>::run(const xtd::func<result_t>& func) -> xtd::threading::tasks::task<result_t> {return factory().start_new(func);}
215 template<typename result_t>
216 auto xtd::threading::tasks::basic_task<result_t>::run(const xtd::func<result_t>& func, const xtd::threading::cancellation_token& cancellation_token) -> xtd::threading::tasks::task<result_t> {return factory().start_new(func, cancellation_token);}
217 template<typename result_t>
218 auto xtd::threading::tasks::basic_task<result_t>::run(const xtd::func<result_t, const xtd::any_object&>& func, const xtd::any_object& state) -> xtd::threading::tasks::task<result_t> {return factory().start_new(func, state);}
219 template<typename result_t>
220 auto xtd::threading::tasks::basic_task<result_t>::run(const xtd::func<result_t, const xtd::any_object&>& func, const xtd::any_object& state, const xtd::threading::cancellation_token& cancellation_token) -> xtd::threading::tasks::task<result_t> {return factory().start_new(func, state, cancellation_token);}
221
222 template<typename result_t>
223 template<typename ...items_t>
224 auto xtd::threading::tasks::basic_task<result_t>::when_all(items_t&&... items) -> task<> {
225 return task_factory {}.start_new([&items...]() mutable {
226 task<>::wait_all(std::forward<items_t>(items)...);
227 });
228 }
229
230 template<typename result_t>
231 template<typename ...items_t>
232 auto xtd::threading::tasks::basic_task<result_t>::when_any(items_t&&... items) -> task<xtd::usize> {
233 return task_factory {}.start_new([&items...]() mutable {
234 return task<>::wait_any(std::forward<items_t>(items)...);
235 });
236 }
237
238 template<typename result_t>
239 auto xtd::threading::tasks::basic_task<result_t>::yield() -> task<result_t> {
240 co_await yield_awaiter {};
241 }
242
243 template<typename result_t>
244 auto xtd::threading::tasks::basic_task<result_t>::run_continuation(auto continuation) -> void {
245 continuation->start();
246 continuation->wait();
247 }
248
249 template<typename result1_t, typename result2_t>
250 inline auto operator &&(const task<result1_t>& t1, const task<result2_t>& t2) -> task<> {
251 return task_factory {}.start_new([t1, t2]() mutable {task<>::wait_all(t1, t2);});
252 }
253
254 template<typename result1_t, typename result2_t>
255 inline auto operator ||(const task<result1_t>& t1, const task<result2_t>& t2) -> task<> {
256 return task_factory {}.start_new([t1, t2]() mutable {task<>::wait_any(t1, t2);});
257 }
259 }
260 }
261}
Represent a polymorphic wrapper capable of holding any type.
Definition any_object.hpp:30
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:65
static auto throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current()) -> void
Throws an exption with specified exception case.
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:40
Propagates notification that operations should be canceled.
Definition cancellation_token.hpp:39
Provides support for creating and scheduling Task objects.
Definition task_factory.hpp:22
auto start_new(auto &&action, const xtd::any_object &state, const xtd::threading::cancellation_token &cancellation_token) const -> xtd::threading::tasks::task< xtd::raw_type< decltype(action(std::declval< const xtd::any_object & >()))> >
Creates and starts a task.
Definition task_factory.hpp:119
auto start_new(auto &&action) const -> xtd::threading::tasks::task< xtd::raw_type< decltype(std::declval< decltype(action)>()())> >
Creates and starts a task.
Definition task_factory.hpp:91
auto start_new(auto &&action, const xtd::any_object &state) const -> xtd::threading::tasks::task< xtd::raw_type< decltype(std::declval< decltype(action)>()(std::declval< const xtd::any_object & >()))> >
Creates and starts a task.
Definition task_factory.hpp:109
auto start_new(auto &&action, const xtd::threading::cancellation_token &cancellation_token) const -> xtd::threading::tasks::task< xtd::raw_type< decltype(std::declval< decltype(action)>()())> >
Creates and starts a task.
Definition task_factory.hpp:100
Represents an asynchronous operation.
Definition task_result.hpp:20
Definition iterable.hpp:15
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
@ argument_out_of_range
The argument is out of range.
Definition exception_case.hpp:35
#define lock_(object)
The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion loc...
Definition lock.hpp:68
@ ran_to_completion
The task completed execution successfully.
Definition task_status.hpp:35
@ 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
auto handle() noexcept -> xtd::intptr
Gets the thread handle of the current thread.
std::int32_t int32
Represents a 32-bit signed integer.
Definition int32.hpp:25
auto as< xtd::int32 >(xtd::any value) -> xtd::int32
Casts a type into another type.
Definition __as_int32.hpp:36
auto new_sptr(args_t &&... args) -> xtd::sptr< type_t >
xtd::new_sptr operator creates a xtd::sptr object.
Definition new_sptr.hpp:24
@ t
The T key.
Definition console_key.hpp:126
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
Contains xtd::threading::tasks::task <> class.