Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[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
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
42                 TResult value;
43                 
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
60                 string ResultAsString {
61                         get {
62                                 if ((Status & (TaskStatus.RanToCompletion)) != 0)
63                                         return "" + value;
64                                 
65                                 return "<value not available>";
66                         }
67                 }
68                 
69                 public static new TaskFactory<TResult> Factory {
70                         get {
71                                 return factory;
72                         }
73                 }
74                 
75                 public Task (Func<TResult> function)
76                         : this (function, TaskCreationOptions.None)
77                 {
78                         
79                 }
80                 
81                 public Task (Func<TResult> function, CancellationToken cancellationToken)
82                         : this (function, cancellationToken, TaskCreationOptions.None)
83                 {
84                         
85                 }
86                 
87                 public Task (Func<TResult> function, TaskCreationOptions creationOptions)
88                         : this (function, CancellationToken.None, creationOptions)
89                 {
90                         
91                 }
92                 
93                 public Task (Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
94                         : base (TaskActionInvoker.Create (function), null, cancellationToken, creationOptions)
95                 {
96                         if (function == null)
97                                 throw new ArgumentNullException ("function");
98                 }
99                 
100                 public Task (Func<object, TResult> function, object state)
101                         : this (function, state, TaskCreationOptions.None)
102                 {
103                         
104                 }
105                 
106                 public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken)
107                         : this (function, state, cancellationToken, TaskCreationOptions.None)
108                 {
109                         
110                 }
111                 
112                 public Task (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
113                         : this (function, state, CancellationToken.None, creationOptions)
114                 {
115                         
116                 }
117
118                 public Task (Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
119                         : base (TaskActionInvoker.Create (function), state, cancellationToken, creationOptions)
120                 {
121                         if (function == null)
122                                 throw new ArgumentNullException ("function");
123                 }
124
125                 internal Task (TaskActionInvoker invoker, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent, Task contAncestor = null)
126                         : base (invoker, state, cancellationToken, creationOptions, parent, contAncestor)
127                 {
128                 }
129
130                 public Task ContinueWith (Action<Task<TResult>> continuationAction)
131                 {
132                         return ContinueWith (continuationAction, TaskContinuationOptions.None);
133                 }
134                 
135                 public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskContinuationOptions continuationOptions)
136                 {
137                         return ContinueWith (continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
138                 }
139                 
140                 public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken)
141                 {
142                         return ContinueWith (continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
143                 }
144                 
145                 public Task ContinueWith (Action<Task<TResult>> continuationAction, TaskScheduler scheduler)
146                 {
147                         return ContinueWith (continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
148                 }
149                 
150                 public Task ContinueWith (Action<Task<TResult>> continuationAction, CancellationToken cancellationToken,
151                                           TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
152                 {
153                         if (continuationAction == null)
154                                 throw new ArgumentNullException ("continuationAction");
155                         if (scheduler == null)
156                                 throw new ArgumentNullException ("scheduler");
157
158                         Task t = new Task (TaskActionInvoker.Create (continuationAction),
159                                            null,
160                                            cancellationToken,
161                                            GetCreationOptions (continuationOptions),
162                                            null,
163                                            this);
164                         ContinueWithCore (t, continuationOptions, scheduler);
165                         
166                         return t;
167                 }
168
169                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction)
170                 {
171                         return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
172                 }
173                 
174                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken)
175                 {
176                         return ContinueWith<TNewResult> (continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
177                 }
178                 
179                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions)
180                 {
181                         return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
182                 }
183                 
184                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler)
185                 {
186                         return ContinueWith<TNewResult> (continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
187                 }
188                 
189                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, TNewResult> continuationFunction,
190                                                                   CancellationToken cancellationToken,
191                                                                   TaskContinuationOptions continuationOptions,
192                                                                   TaskScheduler scheduler)
193                 {
194                         if (continuationFunction == null)
195                                 throw new ArgumentNullException ("continuationFunction");
196                         if (scheduler == null)
197                                 throw new ArgumentNullException ("scheduler");
198
199                         var t = new Task<TNewResult> (TaskActionInvoker.Create (continuationFunction),
200                                                       null,
201                                                       cancellationToken,
202                                                       GetCreationOptions (continuationOptions),
203                                                       null,
204                                                       this);
205                         ContinueWithCore (t, continuationOptions, scheduler);
206                         
207                         return t;
208                 }
209
210                 internal bool TrySetResult (TResult result)
211                 {
212                         if (IsCompleted)
213                                 return false;
214                         
215                         if (!executing.TryRelaxedSet ()) {
216                                 var sw = new SpinWait ();
217                                 while (!IsCompleted)
218                                         sw.SpinOnce ();
219
220                                 return false;
221                         }
222                         
223                         Status = TaskStatus.Running;
224
225                         this.value = result;
226                         Thread.MemoryBarrier ();
227
228                         Finish ();
229
230                         return true;
231                 }
232                 
233 #if NET_4_5
234
235                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state)
236                 {
237                         return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
238                 }
239
240                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken)
241                 {
242                         return ContinueWith (continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
243                 }
244
245                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
246                 {
247                         return ContinueWith (continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
248                 }
249
250                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler)
251                 {
252                         return ContinueWith (continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
253                 }
254
255                 public Task ContinueWith (Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken,
256                                                                   TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
257                 {
258                         if (continuationAction == null)
259                                 throw new ArgumentNullException ("continuationAction");
260                         if (scheduler == null)
261                                 throw new ArgumentNullException ("scheduler");
262
263                         var t = new Task (TaskActionInvoker.Create (continuationAction),
264                                           state,
265                                           cancellationToken,
266                                           GetCreationOptions (continuationOptions),
267                                           null,
268                                           this);
269
270                         ContinueWithCore (t, continuationOptions, scheduler);
271
272                         return t;
273                 }
274
275                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state)
276                 {
277                         return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
278                 }
279
280                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken)
281                 {
282                         return ContinueWith<TNewResult> (continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
283                 }
284
285                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskContinuationOptions continuationOptions)
286                 {
287                         return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
288                 }
289
290                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskScheduler scheduler)
291                 {
292                         return ContinueWith<TNewResult> (continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
293                 }
294
295                 public Task<TNewResult> ContinueWith<TNewResult> (Func<Task<TResult>, object, TNewResult> continuationFunction, object state,
296                                                                                                                   CancellationToken cancellationToken,
297                                                                                                                   TaskContinuationOptions continuationOptions,
298                                                                                                                   TaskScheduler scheduler)
299                 {
300                         if (continuationFunction == null)
301                                 throw new ArgumentNullException ("continuationFunction");
302                         if (scheduler == null)
303                                 throw new ArgumentNullException ("scheduler");
304
305                         var t = new Task<TNewResult> (TaskActionInvoker.Create (continuationFunction),
306                                                       state,
307                                                       cancellationToken,
308                                                       GetCreationOptions (continuationOptions),
309                                                       null,
310                                                       this);
311
312                         ContinueWithCore (t, continuationOptions, scheduler);
313
314                         return t;
315                 }
316
317                 public new ConfiguredTaskAwaitable<TResult> ConfigureAwait (bool continueOnCapturedContext)
318                 {
319                         return new ConfiguredTaskAwaitable<TResult> (this, continueOnCapturedContext);
320                 }
321
322                 public new TaskAwaiter<TResult> GetAwaiter ()
323                 {
324                         return new TaskAwaiter<TResult> (this);
325                 }
326 #endif
327         }
328 }
329 #endif