Task_T.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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
  30. using System.Runtime.CompilerServices;
  31. namespace System.Threading.Tasks
  32. {
  33. [System.Diagnostics.DebuggerDisplay ("Id = {Id}, Status = {Status}, Result = {ResultAsString}")]
  34. [System.Diagnostics.DebuggerTypeProxy (typeof (TaskDebuggerView))]
  35. public class Task<TResult> : Task
  36. {
  37. static readonly TaskFactory<TResult> factory = new TaskFactory<TResult> ();
  38. TResult value;
  39. [System.Diagnostics.DebuggerBrowsable (System.Diagnostics.DebuggerBrowsableState.Never)]
  40. public TResult Result {
  41. get {
  42. if (!IsCompleted)
  43. Wait ();
  44. if (IsCanceled)
  45. throw new AggregateException (new TaskCanceledException (this));
  46. if (Exception != null)
  47. throw Exception;
  48. return value;
  49. }
  50. internal set {
  51. this.value = value;
  52. }
  53. }
  54. string ResultAsString {
  55. get {
  56. if ((Status & (TaskStatus.RanToCompletion)) != 0)
  57. return "" + value;
  58. return "<value not available>";
  59. }
  60. }
  61. public static new TaskFactory<TResult> Factory {
  62. get {
  63. return factory;
  64. }
  65. }
  66. public Task (Func<TResult> function)
  67. : this (function, TaskCreationOptions.None)
  68. {
  69. }
  70. public Task (Func<TResult> function, CancellationToken cancellationToken)
  71. : this (function, cancellationToken, TaskCreationOptions.None)
  72. {
  73. }
  74. public Task (Func<TResult> function, TaskCreationOptions creationOptions)
  75. : this (function, CancellationToken.None, creationOptions)
  76. {
  77. }
  78. public Task (Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
  79. : base (TaskActionInvoker.Create (function), null, cancellationToken, creationOptions)
  80. {
  81. if (function == null)
  82. throw new ArgumentNullException ("function");
  83. }
  84. public Task (Func<object, TResult> function, object state)
  85. : this (function, state, TaskCreationOptions.None)
  86. {
  87. }
  88. public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken)
  89. : this (function, state, cancellationToken, TaskCreationOptions.None)
  90. {
  91. }
  92. public Task (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
  93. : this (function, state, CancellationToken.None, creationOptions)
  94. {
  95. }
  96. public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
  97. : base (TaskActionInvoker.Create (function), state, cancellationToken, creationOptions)
  98. {
  99. if (function == null)
  100. throw new ArgumentNullException ("function");
  101. }
  102. internal Task (TaskActionInvoker invoker, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent, Task contAncestor = null, bool ignoreCancellation = false)
  103. : base (invoker, state, cancellationToken, creationOptions, parent, contAncestor, ignoreCancellation)
  104. {
  105. }
  106. public Task ContinueWith (Action<Task<TResult>> continuationAction)
  107. {
  108. return ContinueWith (continuationAction, TaskContinuationOptions.None);
  109. }
  110. public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskContinuationOptions continuationOptions)
  111. {
  112. return ContinueWith (continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  113. }
  114. public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken)
  115. {
  116. return ContinueWith (continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  117. }
  118. public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskScheduler scheduler)
  119. {
  120. return ContinueWith (continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  121. }
  122. public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken,
  123. TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
  124. {
  125. if (continuationAction == null)
  126. throw new ArgumentNullException ("continuationAction");
  127. if (scheduler == null)
  128. throw new ArgumentNullException ("scheduler");
  129. Task t = new Task (TaskActionInvoker.Create (continuationAction),
  130. null,
  131. cancellationToken,
  132. GetCreationOptions (continuationOptions),
  133. null,
  134. this);
  135. ContinueWithCore (t, continuationOptions, scheduler);
  136. return t;
  137. }
  138. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction)
  139. {
  140. return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
  141. }
  142. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken)
  143. {
  144. return ContinueWith<TNewResult> (continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  145. }
  146. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions)
  147. {
  148. return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  149. }
  150. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler)
  151. {
  152. return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  153. }
  154. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction,
  155. CancellationToken cancellationToken,
  156. TaskContinuationOptions continuationOptions,
  157. TaskScheduler scheduler)
  158. {
  159. if (continuationFunction == null)
  160. throw new ArgumentNullException ("continuationFunction");
  161. if (scheduler == null)
  162. throw new ArgumentNullException ("scheduler");
  163. var t = new Task<TNewResult> (TaskActionInvoker.Create (continuationFunction),
  164. null,
  165. cancellationToken,
  166. GetCreationOptions (continuationOptions),
  167. null,
  168. this);
  169. ContinueWithCore (t, continuationOptions, scheduler);
  170. return t;
  171. }
  172. internal bool TrySetResult (TResult result)
  173. {
  174. if (IsCompleted)
  175. return false;
  176. if (!executing.TryRelaxedSet ()) {
  177. var sw = new SpinWait ();
  178. while (!IsCompleted)
  179. sw.SpinOnce ();
  180. return false;
  181. }
  182. Status = TaskStatus.Running;
  183. this.value = result;
  184. Thread.MemoryBarrier ();
  185. Finish ();
  186. return true;
  187. }
  188. #if NET_4_5
  189. public
  190. #else
  191. internal
  192. #endif
  193. Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken,
  194. TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
  195. {
  196. if (continuationAction == null)
  197. throw new ArgumentNullException ("continuationAction");
  198. if (scheduler == null)
  199. throw new ArgumentNullException ("scheduler");
  200. var t = new Task (TaskActionInvoker.Create (continuationAction),
  201. state,
  202. cancellationToken,
  203. GetCreationOptions (continuationOptions),
  204. null,
  205. this);
  206. ContinueWithCore (t, continuationOptions, scheduler);
  207. return t;
  208. }
  209. #if NET_4_5
  210. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state)
  211. {
  212. return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
  213. }
  214. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken)
  215. {
  216. return ContinueWith (continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  217. }
  218. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
  219. {
  220. return ContinueWith (continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  221. }
  222. public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler)
  223. {
  224. return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  225. }
  226. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state)
  227. {
  228. return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
  229. }
  230. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken)
  231. {
  232. return ContinueWith<TNewResult> (continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
  233. }
  234. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskContinuationOptions continuationOptions)
  235. {
  236. return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
  237. }
  238. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskScheduler scheduler)
  239. {
  240. return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
  241. }
  242. public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
  243. CancellationToken cancellationToken,
  244. TaskContinuationOptions continuationOptions,
  245. TaskScheduler scheduler)
  246. {
  247. if (continuationFunction == null)
  248. throw new ArgumentNullException ("continuationFunction");
  249. if (scheduler == null)
  250. throw new ArgumentNullException ("scheduler");
  251. var t = new Task<TNewResult> (TaskActionInvoker.Create (continuationFunction),
  252. state,
  253. cancellationToken,
  254. GetCreationOptions (continuationOptions),
  255. null,
  256. this);
  257. ContinueWithCore (t, continuationOptions, scheduler);
  258. return t;
  259. }
  260. public new ConfiguredTaskAwaitable<TResult> ConfigureAwait (bool continueOnCapturedContext)
  261. {
  262. return new ConfiguredTaskAwaitable<TResult> (this, continueOnCapturedContext);
  263. }
  264. public new TaskAwaiter<TResult> GetAwaiter ()
  265. {
  266. return new TaskAwaiter<TResult> (this);
  267. }
  268. internal static Task<TResult> FromException (Exception ex)
  269. {
  270. var tcs = new TaskCompletionSource<TResult>();
  271. tcs.TrySetException (ex);
  272. return tcs.Task;
  273. }
  274. #endif
  275. }
  276. }
  277. #endif