Advertisement
Guest User

Untitled

a guest
Feb 24th, 2015
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.26 KB | None | 0 0
  1. unit ThreadingEx;
  2.  
  3. interface
  4.  
  5. uses
  6. SysUtils,
  7. Threading;
  8.  
  9. type
  10. TAction<T> = reference to procedure(const arg: T);
  11.  
  12. TTaskContinuationOptions = (
  13. NotOnCompleted,
  14. NotOnFaulted,
  15. NotOnCanceled,
  16. OnlyOnCompleted,
  17. OnlyOnFaulted,
  18. OnlyOnCanceled
  19. );
  20.  
  21. ITaskEx = interface(ITask)
  22. ['{3AE1A614-27AA-4B5A-BC50-42483650E20D}']
  23. function GetExceptObj: Exception;
  24. function GetStatus: TTaskStatus;
  25. function ContinueWith(const continuationAction: TAction<ITaskEx>;
  26. continuationOptions: TTaskContinuationOptions): ITaskEx;
  27. function ContinueWithGui(const continuationAction: TAction<ITaskEx>;
  28. continuationOptions: TTaskContinuationOptions): ITaskEx;
  29. property ExceptObj: Exception read GetExceptObj;
  30. property Status: TTaskStatus read GetStatus;
  31. end;
  32.  
  33. TTaskEx = class(TTask, ITaskEx)
  34. private
  35. fExceptObj: Exception;
  36. function GetExceptObj: Exception;
  37. protected
  38. function ContinueWith(const continuationAction: TAction<ITaskEx>;
  39. continuationOptions: TTaskContinuationOptions): ITaskEx;
  40. function ContinueWithGui(const continuationAction: TAction<ITaskEx>;
  41. continuationOptions: TTaskContinuationOptions): ITaskEx;
  42. public
  43. destructor Destroy; override;
  44. class function Run(const action: TProc): ITaskEx; static;
  45. end;
  46.  
  47. implementation
  48.  
  49. uses
  50. Classes;
  51.  
  52. { TTaskEx }
  53.  
  54. function TTaskEx.ContinueWith(const continuationAction: TAction<ITaskEx>;
  55. continuationOptions: TTaskContinuationOptions): ITaskEx;
  56. begin
  57. Result := TTaskEx.Run(
  58. procedure
  59. var
  60. task: ITaskEx;
  61. doContinue: Boolean;
  62. aggregatedException: EAggregateException;
  63. begin
  64. task := Self;
  65. if not IsComplete then
  66. DoneEvent.WaitFor;
  67. aggregatedException := GetExceptionObject as EAggregateException;
  68. if Assigned(aggregatedException) and (aggregatedException.Count = 1) then
  69. fExceptObj := aggregatedException[0] else
  70. fExceptObj := nil;
  71. case continuationOptions of
  72. NotOnCompleted: doContinue := GetStatus <> TTaskStatus.Completed;
  73. NotOnFaulted: doContinue := GetStatus <> TTaskStatus.Exception;
  74. NotOnCanceled: doContinue := GetStatus <> TTaskStatus.Canceled;
  75. OnlyOnCompleted: doContinue := GetStatus = TTaskStatus.Completed;
  76. OnlyOnFaulted: doContinue := GetStatus = TTaskStatus.Exception;
  77. OnlyOnCanceled: doContinue := GetStatus = TTaskStatus.Canceled;
  78. else
  79. doContinue := False;
  80. end;
  81. if doContinue then
  82. continuationAction(task);
  83. end);
  84. end;
  85.  
  86. function TTaskEx.ContinueWithGui(
  87. const continuationAction: TAction<ITaskEx>;
  88. continuationOptions: TTaskContinuationOptions): ITaskEx;
  89. var
  90. Res: ITaskEx;
  91. begin
  92. Result := TTaskEx.Run(
  93. procedure
  94. var
  95. task: ITaskEx;
  96. doContinue: Boolean;
  97. aggregatedException: EAggregateException;
  98. begin
  99. task := Self;
  100. if not IsComplete then
  101. DoneEvent.WaitFor;
  102. aggregatedException := GetExceptionObject as EAggregateException;
  103. if Assigned(aggregatedException) and (aggregatedException.Count = 1) then
  104. fExceptObj := aggregatedException[0] else
  105. fExceptObj := nil;
  106. case continuationOptions of
  107. NotOnCompleted: doContinue := GetStatus <> TTaskStatus.Completed;
  108. NotOnFaulted: doContinue := GetStatus <> TTaskStatus.Exception;
  109. NotOnCanceled: doContinue := GetStatus <> TTaskStatus.Canceled;
  110. OnlyOnCompleted: doContinue := GetStatus = TTaskStatus.Completed;
  111. OnlyOnFaulted: doContinue := GetStatus = TTaskStatus.Exception;
  112. OnlyOnCanceled: doContinue := GetStatus = TTaskStatus.Canceled;
  113. else
  114. doContinue := False;
  115. end;
  116. if doContinue then
  117. TThread.Queue(nil,
  118. procedure
  119. begin
  120. continuationAction(task);
  121. end);
  122. end);
  123. end;
  124.  
  125. destructor TTaskEx.Destroy;
  126. begin
  127. fExceptObj.Free;
  128. inherited;
  129. end;
  130.  
  131. function TTaskEx.GetExceptObj: Exception;
  132. begin
  133. Result := fExceptObj;
  134. end;
  135.  
  136. class function TTaskEx.Run(const action: TProc): ITaskEx;
  137. var
  138. task: TTaskEx;
  139. begin
  140. task := TTaskEx.Create(nil, TNotifyEvent(nil), action, TThreadPool.Default, nil);
  141. Result := task.Start as ITaskEx;
  142. end;
  143.  
  144. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement