|
4 | 4 | #include <YY/Base/Containers/DoublyLinkedList.h> |
5 | 5 | #include <YY/Base/Sync/SRWLock.h> |
6 | 6 | #include <YY/Base/Sync/AutoLock.h> |
| 7 | +#include <YY/Base/Containers/Optional.h> |
7 | 8 |
|
8 | 9 | #pragma pack(push, __YY_PACKING) |
9 | 10 |
|
@@ -158,11 +159,10 @@ namespace YY |
158 | 159 | /// <returns></returns> |
159 | 160 | virtual bool __YYAPI Cancel() |
160 | 161 | { |
161 | | - if ((AsyncStatus)YY::Sync::CompareExchange(reinterpret_cast<volatile uint32_t*>(&eStatus), uint32_t(AsyncStatus::Canceled), uint32_t(AsyncStatus::Started)) != AsyncStatus::Started) |
| 162 | + if (!BeginNotifyCompletedHandlers(AsyncStatus::Canceled)) |
162 | 163 | { |
163 | 164 | return false; |
164 | 165 | } |
165 | | - |
166 | 166 | WakeByAddressAll((PVOID)&eStatus); |
167 | 167 | NotifyCompletedHandlers(); |
168 | 168 | return true; |
@@ -217,6 +217,8 @@ namespace YY |
217 | 217 | NotifyCompletedHandlers(); |
218 | 218 | return true; |
219 | 219 | } |
| 220 | + |
| 221 | + virtual void __YYAPI NotifyCompletedHandlers() = 0; |
220 | 222 | }; |
221 | 223 |
|
222 | 224 | template<typename ResultType_> |
@@ -302,6 +304,12 @@ namespace YY |
302 | 304 | Delegate oCompletedDelegate; |
303 | 305 |
|
304 | 306 | public: |
| 307 | + /// <summary> |
| 308 | + /// 如果操作成功,则获取异步操作的结果。 |
| 309 | + /// </summary> |
| 310 | + /// <returns>指向 ResultType 的引用,表示获取到的结果。</returns> |
| 311 | + virtual void __YYAPI GetResult() = 0; |
| 312 | + |
305 | 313 | bool __YYAPI AddCompletedHandler(_In_ AsyncOperationCompletedHandler* _pHandler) |
306 | 314 | { |
307 | 315 | if (!_pHandler) |
@@ -340,6 +348,110 @@ namespace YY |
340 | 348 | _oCompletedDelegate.InvokeAllHandlers(this, GetStatus()); |
341 | 349 | } |
342 | 350 | }; |
| 351 | + |
| 352 | + template<typename ResultType_> |
| 353 | + class AsyncOperationImpl : public AsyncOperation<ResultType_> |
| 354 | + { |
| 355 | + public: |
| 356 | + using ResultType = ResultType_; |
| 357 | + using AsyncOperationCompletedHandler = typename AsyncOperation<ResultType>::AsyncOperationCompletedHandler; |
| 358 | + using Delegate = typename AsyncOperation<ResultType>::Delegate; |
| 359 | + |
| 360 | + private: |
| 361 | + union |
| 362 | + { |
| 363 | + byte oResultBuffer[sizeof(ResultType)] = {}; |
| 364 | + ResultType oResult; |
| 365 | + }; |
| 366 | + |
| 367 | + public: |
| 368 | + ResultType& __YYAPI GetResult() override |
| 369 | + { |
| 370 | + if (!WaitTask()) |
| 371 | + { |
| 372 | + throw YY::Exception(_S("等待异步任务WaitTask失败。"), E_FAIL); |
| 373 | + } |
| 374 | + |
| 375 | + switch (GetStatus()) |
| 376 | + { |
| 377 | + case AsyncStatus::Completed: |
| 378 | + break; |
| 379 | + case AsyncStatus::Canceled: |
| 380 | + throw YY::OperationCanceledException(_S("异步任务已经被取消。")); |
| 381 | + break; |
| 382 | + case AsyncStatus::Error: |
| 383 | + throw YY::Exception(GetErrorCode()); |
| 384 | + break; |
| 385 | + default: |
| 386 | + throw YY::Exception(_S("异步任务状态不符合预期。"), E_FAIL); |
| 387 | + break; |
| 388 | + } |
| 389 | + |
| 390 | + return oResult; |
| 391 | + } |
| 392 | + |
| 393 | + protected: |
| 394 | + bool __YYAPI Resolve(ResultType&& _oResult) |
| 395 | + { |
| 396 | + if (!BeginNotifyCompletedHandlers(AsyncStatus::Completed)) |
| 397 | + { |
| 398 | + return false; |
| 399 | + } |
| 400 | + |
| 401 | + new (oResultBuffer) ResultType(_oResult); |
| 402 | + NotifyCompletedHandlers(); |
| 403 | + return true; |
| 404 | + } |
| 405 | + }; |
| 406 | + |
| 407 | + template<> |
| 408 | + class AsyncOperationImpl<void> : public AsyncOperation<void> |
| 409 | + { |
| 410 | + public: |
| 411 | + using ResultType = void; |
| 412 | + using AsyncOperationCompletedHandler = typename AsyncOperation<ResultType>::AsyncOperationCompletedHandler; |
| 413 | + using Delegate = typename AsyncOperation<ResultType>::Delegate; |
| 414 | + |
| 415 | + private: |
| 416 | + |
| 417 | + public: |
| 418 | + void __YYAPI GetResult() override |
| 419 | + { |
| 420 | + if (!WaitTask()) |
| 421 | + { |
| 422 | + throw YY::Exception(_S("等待异步任务WaitTask失败。"), E_FAIL); |
| 423 | + } |
| 424 | + |
| 425 | + switch (GetStatus()) |
| 426 | + { |
| 427 | + case AsyncStatus::Completed: |
| 428 | + break; |
| 429 | + case AsyncStatus::Canceled: |
| 430 | + throw YY::OperationCanceledException(_S("异步任务已经被取消。")); |
| 431 | + break; |
| 432 | + case AsyncStatus::Error: |
| 433 | + throw YY::Exception(GetErrorCode()); |
| 434 | + break; |
| 435 | + default: |
| 436 | + throw YY::Exception(_S("异步任务状态不符合预期。"), E_FAIL); |
| 437 | + break; |
| 438 | + } |
| 439 | + |
| 440 | + return; |
| 441 | + } |
| 442 | + |
| 443 | + protected: |
| 444 | + bool __YYAPI Resolve(void) |
| 445 | + { |
| 446 | + if (!BeginNotifyCompletedHandlers(AsyncStatus::Completed)) |
| 447 | + { |
| 448 | + return false; |
| 449 | + } |
| 450 | + |
| 451 | + NotifyCompletedHandlers(); |
| 452 | + return true; |
| 453 | + } |
| 454 | + }; |
343 | 455 | } |
344 | 456 | } |
345 | 457 | } |
|
0 commit comments