Task_T.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. //
  2. // Task_T.cs
  3. //
  4. // Authors:
  5. // Marek Safar <[email protected]>
  6. //
  7. // Copyright (c) 2008 Jérémie "Garuma" Laval
  8. // Copyright 2011 Xamarin Inc.
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining a copy
  11. // of this software and associated documentation files (the "Software"), to deal
  12. // in the Software without restriction, including without limitation the rights
  13. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. // copies of the Software, and to permit persons to whom the Software is
  15. // furnished to do so, subject to the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be included in
  18. // all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. // THE SOFTWARE.
  27. //
  28. //
  29. #if NET_4_0 || MOBILE
  30. using System;
  31. using System.Runtime.CompilerServices;
  32. namespace System.Threading.Tasks
  33. {
  34. [System.Diagnostics.DebuggerDisplay ("Id = {Id}, Status = {Status}, Result = {ResultAsString}")]
  35. [System.Diagnostics.DebuggerTypeProxy (typeof (TaskDebuggerView))]
  36. public class Task<TResult> : Task
  37. {
  38. static readonly TaskFactory<TResult> factory = new TaskFactory<TResult> ();
  39. static readonly Action<object> emptyAction = delegate (object o) {};
  40. TResult value;
  41. Func<object, TResult> function;
  42. Func<TResult> simpleFunction;
  43. object state;
  44. [System.Diagnostics.DebuggerBrowsable (System.Diagnostics.DebuggerBrowsableState.Never)]
  45. public TResult Result {
  46. get {
  47. if (!IsCompleted)
  48. Wait ();
  49. if (IsCanceled)
  50. throw new AggregateException (new TaskCanceledException (this));
  51. if (Exception != null)
  52. throw Exception;
  53. return value;
  54. }
  55. internal set {
  56. this.value = value;
  57. }
  58. }
  59. string ResultAsString {
  60. get {
  61. if ((Status & (TaskStatus.RanToCompletion)) != 0)
  62. return "" + value;
  63. return "<value not available>";
  64. }
  65. }
  66. public static new TaskFactory<TResult> Factory {
  67. get {
  68. return factory;
  69. }
  70. }
  71. public Task (Func<TResult> function) : this (function, TaskCreationOptions.None)
  72. {
  73. }
  74. public Task (Func<TResult> function, CancellationToken cancellationToken)
  75. : this (function, cancellationToken, TaskCreationOptions.None)
  76. {
  77. }
  78. public Task (Func<TResult> function, TaskCreationOptions creationOptions)
  79. : this (function, CancellationToken.None, creationOptions)
  80. {
  81. }
  82. public Task (Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
  83. : base (emptyAction, null, cancellationToken, creationOptions)
  84. {
  85. if (function == null)
  86. throw new ArgumentNullException ("function");
  87. this.simpleFunction = function;
  88. this.state = null;
  89. }
  90. public Task (Func<object, TResult> function, object state) : this (function, state, TaskCreationOptions.None)
  91. {
  92. }
  93. public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken)
  94. : this (function, state, cancellationToken, TaskCreationOptions.None)
  95. {
  96. }
  97. public Task (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
  98. : this (function, state, CancellationToken.None, creationOptions)
  99. {
  100. }
  101. public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
  102. : base (emptyAction, state, cancellationToken, creationOptions)
  103. {
  104. if (function == null)
  105. throw new ArgumentNullException ("function");
  106. this.function = function;
  107. this.state = state;
  108. }
  109. internal Task (Func<object, TResult> function,
  110. object state,
  111. CancellationToken cancellationToken,
  112. TaskCreationOptions creationOptions,
  113. Task parent)
  114. : base (emptyAction, state, cancellationToken, creationOptions, parent)
  115. {
  116. this.function = function;
  117. this.state = state;
  118. }
  119. internal override void InnerInvoke ()
  120. {
  121. if (function != null)
  122. value = function (state);
  123. else if (simpleFunction != null)
  124. value = simpleFunction ();
  125. function = null;
  126. simpleFunction = null;
  127. state = null;
  128. }
  129. public Task ContinueWith (Action<Task<TResult>> continuationAction)
  130. {
  131. return ContinueWith (continuationAction, TaskContinuationOptions.None);
  132. }
  133. public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskContinuationOptions continuationOptions)
  134. {
  135. return ContinueWith (continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  136. }
  137. public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken)
  138. {
  139. return ContinueWith (continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  140. }
  141. public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskScheduler scheduler)
  142. {
  143. return ContinueWith (continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  144. }
  145. public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken,
  146. TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
  147. {
  148. if (continuationAction == null)
  149. throw new ArgumentNullException ("continuationAction");
  150. if (scheduler == null)
  151. throw new ArgumentNullException ("scheduler");
  152. Task t = new Task (l => continuationAction ((Task<TResult>)l),
  153. this,
  154. cancellationToken,
  155. GetCreationOptions (continuationOptions),
  156. this);
  157. ContinueWithCore (t, continuationOptions, scheduler);
  158. return t;
  159. }
  160. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction)
  161. {
  162. return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
  163. }
  164. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken)
  165. {
  166. return ContinueWith<TNewResult> (continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  167. }
  168. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions)
  169. {
  170. return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  171. }
  172. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler)
  173. {
  174. return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  175. }
  176. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction,
  177. CancellationToken cancellationToken,
  178. TaskContinuationOptions continuationOptions,
  179. TaskScheduler scheduler)
  180. {
  181. if (continuationFunction == null)
  182. throw new ArgumentNullException ("continuationFunction");
  183. if (scheduler == null)
  184. throw new ArgumentNullException ("scheduler");
  185. Task<TNewResult> t = new Task<TNewResult> ((o) => continuationFunction ((Task<TResult>)o),
  186. this,
  187. cancellationToken,
  188. GetCreationOptions (continuationOptions),
  189. this);
  190. ContinueWithCore (t, continuationOptions, scheduler);
  191. return t;
  192. }
  193. #if NET_4_5
  194. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state)
  195. {
  196. return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
  197. }
  198. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken)
  199. {
  200. return ContinueWith (continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  201. }
  202. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
  203. {
  204. return ContinueWith (continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  205. }
  206. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler)
  207. {
  208. return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  209. }
  210. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken,
  211. TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
  212. {
  213. if (continuationAction == null)
  214. throw new ArgumentNullException ("continuationAction");
  215. if (scheduler == null)
  216. throw new ArgumentNullException ("scheduler");
  217. var t = new Task (l => continuationAction (this, l),
  218. state,
  219. cancellationToken,
  220. GetCreationOptions (continuationOptions),
  221. this);
  222. ContinueWithCore (t, continuationOptions, scheduler);
  223. return t;
  224. }
  225. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state)
  226. {
  227. return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
  228. }
  229. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken)
  230. {
  231. return ContinueWith<TNewResult> (continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  232. }
  233. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskContinuationOptions continuationOptions)
  234. {
  235. return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  236. }
  237. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskScheduler scheduler)
  238. {
  239. return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  240. }
  241. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
  242. CancellationToken cancellationToken,
  243. TaskContinuationOptions continuationOptions,
  244. TaskScheduler scheduler)
  245. {
  246. if (continuationFunction == null)
  247. throw new ArgumentNullException ("continuationFunction");
  248. if (scheduler == null)
  249. throw new ArgumentNullException ("scheduler");
  250. var t = new Task<TNewResult> (l => continuationFunction (this, l),
  251. state,
  252. cancellationToken,
  253. GetCreationOptions (continuationOptions),
  254. this);
  255. ContinueWithCore (t, continuationOptions, scheduler);
  256. return t;
  257. }
  258. public new ConfiguredTaskAwaitable<TResult> ConfigureAwait (bool continueOnCapturedContext)
  259. {
  260. return new ConfiguredTaskAwaitable<TResult> (this, continueOnCapturedContext);
  261. }
  262. public new TaskAwaiter<TResult> GetAwaiter ()
  263. {
  264. return new TaskAwaiter<TResult> (this);
  265. }
  266. #endif
  267. }
  268. }
  269. #endif