Move things around in Task and Task_T
[mono.git] / mcs / class / corlib / System.Threading.Tasks / Task_T.cs
1 //
2 // Task_T.cs
3 //
4 // Authors:
5 //    Marek Safar  <marek.safar@gmail.com>
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
30 #if NET_4_0 || MOBILE
31 using System;
32 using System.Runtime.CompilerServices;
33
34 namespace System.Threading.Tasks
35 {
36         [System.Diagnostics.DebuggerDisplay ("Id = {Id}, Status = {Status}, Result = {ResultAsString}")]
37         [System.Diagnostics.DebuggerTypeProxy (typeof (TaskDebuggerView))]
38         public class Task<TResult> : Task
39         {
40                 static readonly TaskFactory<TResult> factory = new TaskFactory<TResult> ();
41                 static readonly Action<object> emptyAction = delegate (object o) {};
42
43                 TResult value;
44                 Func<object, TResult> function;
45                 Func<TResult> simpleFunction;
46                 object state;
47                 
48                 [System.Diagnostics.DebuggerBrowsable (System.Diagnostics.DebuggerBrowsableState.Never)]
49                 public TResult Result {
50                         get {
51                                 if (!IsCompleted)
52                                         Wait ();
53                                 if (Exception != null)
54                                         throw Exception;
55                                 return value;
56                         }
57                         internal set {
58                                 this.value = value;
59                         }
60                 }
61
62                 string ResultAsString {
63                         get {
64                                 if ((Status & (TaskStatus.RanToCompletion)) != 0)
65                                         return "" + value;
66                                 
67                                 return "<value not available>";
68                         }
69                 }
70                 
71                 public static new TaskFactory<TResult> Factory {
72                         get {
73                                 return factory;
74                         }
75                 }
76                 
77                 public Task (Func<TResult> function) : this (function, TaskCreationOptions.None)
78                 {
79                         
80                 }
81                 
82                 public Task (Func<TResult> function, CancellationToken cancellationToken)
83                         : this (function, cancellationToken, TaskCreationOptions.None)
84                 {
85                         
86                 }
87                 
88                 public Task (Func<TResult> function, TaskCreationOptions creationOptions)
89                         : this (function, CancellationToken.None, creationOptions)
90                 {
91                         
92                 }
93                 
94                 public Task (Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
95                         : base (emptyAction, null, cancellationToken, creationOptions)
96                 {
97                         if (function == null)
98                                 throw new ArgumentNullException ("function");
99
100                         this.simpleFunction = function;
101                         this.state = null;
102                 }
103                 
104                 public Task (Func<object, TResult> function, object state) : this (function, state, TaskCreationOptions.None)
105                 {
106                         
107                 }
108                 
109                 public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken)
110                         : this (function, state, cancellationToken, TaskCreationOptions.None)
111                 {
112                         
113                 }
114                 
115                 public Task (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
116                         : this (function, state, CancellationToken.None, creationOptions)
117                 {
118                         
119                 }
120
121                 public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
122                         : base (emptyAction, state, cancellationToken, creationOptions)
123                 {
124                         if (function == null)
125                                 throw new ArgumentNullException ("function");
126
127                         this.function = function;
128                         this.state = state;
129                 }
130
131                 internal Task (Func<object, TResult> function,
132                                object state,
133                                CancellationToken cancellationToken,
134                                TaskCreationOptions creationOptions,
135                                Task parent)
136                         : base (emptyAction, state, cancellationToken, creationOptions, parent)
137                 {
138                         this.function = function;
139                         this.state = state;
140                 }
141                 
142                 internal override void InnerInvoke ()
143                 {
144                         if (function != null)
145                                 value = function (state);
146                         else if (simpleFunction != null)
147                                 value = simpleFunction ();
148                         
149                         function = null;
150                         simpleFunction = null;
151                         state = null;
152                 }
153                 
154                 public Task ContinueWith (Action<Task<TResult>> continuationAction)
155                 {
156                         return ContinueWith (continuationAction, TaskContinuationOptions.None);
157                 }
158                 
159                 public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskContinuationOptions continuationOptions)
160                 {
161                         return ContinueWith (continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
162                 }
163                 
164                 public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken)
165                 {
166                         return ContinueWith (continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
167                 }
168                 
169                 public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskScheduler scheduler)
170                 {
171                         return ContinueWith (continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
172                 }
173                 
174                 public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken,
175                                           TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
176                 {
177                         if (continuationAction == null)
178                                 throw new ArgumentNullException ("continuationAction");
179                         if (scheduler == null)
180                                 throw new ArgumentNullException ("scheduler");
181
182                         Task t = new Task (l => continuationAction ((Task<TResult>)l),
183                                            this,
184                                            cancellationToken,
185                                            GetCreationOptions (continuationOptions),
186                                            this);
187                         ContinueWithCore (t, continuationOptions, scheduler);
188                         
189                         return t;
190                 }
191
192                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction)
193                 {
194                         return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
195                 }
196                 
197                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken)
198                 {
199                         return ContinueWith<TNewResult> (continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
200                 }
201                 
202                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions)
203                 {
204                         return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
205                 }
206                 
207                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler)
208                 {
209                         return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
210                 }
211                 
212                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction,
213                                                                   CancellationToken cancellationToken,
214                                                                   TaskContinuationOptions continuationOptions,
215                                                                   TaskScheduler scheduler)
216                 {
217                         if (continuationFunction == null)
218                                 throw new ArgumentNullException ("continuationFunction");
219                         if (scheduler == null)
220                                 throw new ArgumentNullException ("scheduler");
221
222                         Task<TNewResult> t = new Task<TNewResult> ((o) => continuationFunction ((Task<TResult>)o),
223                                                                    this,
224                                                                    cancellationToken,
225                                                                    GetCreationOptions (continuationOptions),
226                                                                    this);
227                         ContinueWithCore (t, continuationOptions, scheduler);
228                         
229                         return t;
230                 }
231                 
232 #if NET_4_5
233
234                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state)
235                 {
236                         return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
237                 }
238
239                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken)
240                 {
241                         return ContinueWith (continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
242                 }
243
244                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
245                 {
246                         return ContinueWith (continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
247                 }
248
249                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler)
250                 {
251                         return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
252                 }
253
254                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken,
255                                                                   TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
256                 {
257                         if (continuationAction == null)
258                                 throw new ArgumentNullException ("continuationAction");
259                         if (scheduler == null)
260                                 throw new ArgumentNullException ("scheduler");
261
262                         var t = new Task (l => continuationAction (this, l),
263                                                            state,
264                                                            cancellationToken,
265                                                            GetCreationOptions (continuationOptions),
266                                                            this);
267
268                         ContinueWithCore (t, continuationOptions, scheduler);
269
270                         return t;
271                 }
272
273                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state)
274                 {
275                         return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
276                 }
277
278                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken)
279                 {
280                         return ContinueWith<TNewResult> (continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
281                 }
282
283                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskContinuationOptions continuationOptions)
284                 {
285                         return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
286                 }
287
288                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskScheduler scheduler)
289                 {
290                         return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
291                 }
292
293                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
294                                                                                                                   CancellationToken cancellationToken,
295                                                                                                                   TaskContinuationOptions continuationOptions,
296                                                                                                                   TaskScheduler scheduler)
297                 {
298                         if (continuationFunction == null)
299                                 throw new ArgumentNullException ("continuationFunction");
300                         if (scheduler == null)
301                                 throw new ArgumentNullException ("scheduler");
302
303                         var t = new Task<TNewResult> (l => continuationFunction (this, l),
304                                                            state,
305                                                            cancellationToken,
306                                                            GetCreationOptions (continuationOptions),
307                                                            this);
308
309                         ContinueWithCore (t, continuationOptions, scheduler);
310
311                         return t;
312                 }
313
314                 public new ConfiguredTaskAwaitable<TResult> ConfigureAwait (bool continueOnCapturedContext)
315                 {
316                         return new ConfiguredTaskAwaitable<TResult> (this, continueOnCapturedContext);
317                 }
318
319                 public new TaskAwaiter<TResult> GetAwaiter ()
320                 {
321                         return new TaskAwaiter<TResult> (this);
322                 }
323 #endif
324         }
325 }
326 #endif