Merge branch 'BigIntegerParse'
[mono.git] / mcs / class / corlib / System.Threading.Tasks / TaskFactory.cs
1 // 
2 // TaskFactory.cs
3 //  
4 // Authors:
5 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
6 //       Marek Safar <marek.safar@gmail.com>
7 // 
8 // Copyright (c) 2009 Jérémie "Garuma" Laval
9 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
10 // 
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28
29 #if NET_4_0
30
31 namespace System.Threading.Tasks
32 {
33         public class TaskFactory
34         {
35                 readonly TaskScheduler scheduler;
36                 TaskCreationOptions creationOptions;
37                 TaskContinuationOptions continuationOptions;
38                 CancellationToken cancellationToken;
39                 
40                 public TaskFactory ()
41                         : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, null)
42                 {
43                 }
44
45                 public TaskFactory (CancellationToken cancellationToken)
46                         : this (cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
47                 {       
48                 }
49
50                 public TaskFactory (TaskScheduler scheduler)
51                         : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler)
52                 {       
53                 }
54                 
55                 public TaskFactory (TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
56                         : this (CancellationToken.None, creationOptions, continuationOptions, null)
57                 {       
58                 }
59                 
60                 public TaskFactory (CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions,
61                                     TaskScheduler scheduler)
62                 {
63                         this.cancellationToken = cancellationToken;
64                         this.scheduler = scheduler;
65                         this.creationOptions = creationOptions;
66                         this.continuationOptions = continuationOptions;
67
68                         CheckContinuationOptions (continuationOptions);
69                 }
70                 
71                 public TaskScheduler Scheduler {
72                         get {
73                                 return scheduler;
74                         }
75                 }
76                 
77                 public TaskContinuationOptions ContinuationOptions {
78                         get {
79                                 return continuationOptions;
80                         }
81                 }
82                 
83                 public TaskCreationOptions CreationOptions {
84                         get {
85                                 return creationOptions;
86                         }
87                 }
88                 
89                 public CancellationToken CancellationToken {
90                         get {
91                                 return cancellationToken;
92                         }
93                 }
94
95                 internal static void CheckContinuationOptions (TaskContinuationOptions continuationOptions)
96                 {
97                         if ((continuationOptions & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) != 0)
98                                 throw new ArgumentOutOfRangeException ("continuationOptions");
99
100                         const TaskContinuationOptions long_running = TaskContinuationOptions.LongRunning | TaskContinuationOptions.ExecuteSynchronously;
101                         if ((continuationOptions & long_running) == long_running)
102                                 throw new ArgumentOutOfRangeException ("continuationOptions", "Synchronous continuations cannot be long running");
103                 }
104                 
105                 #region StartNew for Task
106                 public Task StartNew (Action action)
107                 {
108                         return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
109                 }
110                 
111                 public Task StartNew (Action action, CancellationToken cancellationToken)
112                 {
113                         return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
114                 }
115                 
116                 public Task StartNew (Action action, TaskCreationOptions creationOptions)
117                 {
118                         return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
119                 }
120
121                 public Task StartNew (Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
122                 {
123                         Task t = new Task (action, cancellationToken, creationOptions);
124
125                         //
126                         // Don't start cancelled task it would throw an exception
127                         //
128                         if (!t.IsCompleted)
129                                 t.Start (scheduler);
130
131                         return t;
132                 }
133                 
134                 public Task StartNew (Action<object> action, object state)
135                 {
136                         return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
137                 }
138                 
139                 public Task StartNew (Action<object> action, object state, CancellationToken cancellationToken)
140                 {
141                         return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
142                 }
143                 
144                 public Task StartNew (Action<object> action, object state, TaskCreationOptions creationOptions)
145                 {
146                         return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
147                 }
148                 
149                 public Task StartNew (Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions,
150                                       TaskScheduler scheduler)
151                 {
152                         Task t = new Task (action, state, cancellationToken, creationOptions);
153
154                         //
155                         // Don't start cancelled task it would throw an exception
156                         //
157                         if (!t.IsCompleted)
158                                 t.Start (scheduler);
159                         
160                         return t;
161                 }
162                 #endregion
163                 
164                 #region StartNew for Task<TResult>      
165                 public Task<TResult> StartNew<TResult> (Func<TResult> function)
166                 {
167                         return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
168                 }
169                 
170                 public Task<TResult> StartNew<TResult> (Func<TResult> function, TaskCreationOptions creationOptions)
171                 {
172                         return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
173
174                 }
175                 
176                 public Task<TResult> StartNew<TResult> (Func<TResult> function, CancellationToken cancellationToken)
177                 {
178                         return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
179                 }
180                 
181                 public Task<TResult> StartNew<TResult> (Func<TResult> function,
182                                                         CancellationToken cancellationToken,
183                                                         TaskCreationOptions creationOptions,
184                                                         TaskScheduler scheduler)
185                 {
186                         var t = new Task<TResult> (function, cancellationToken, creationOptions);
187
188                         //
189                         // Don't start cancelled task it would throw an exception
190                         //
191                         if (!t.IsCompleted)
192                                 t.Start (scheduler);
193
194                         return t;
195                 }
196                 
197                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state)
198                 {
199                         return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
200                 }
201                 
202                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, CancellationToken cancellationToken)
203                 {
204                         return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
205                 }
206                 
207                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
208                 {
209                         return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
210                 }
211                 
212                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state,
213                                                         CancellationToken cancellationToken,
214                                                         TaskCreationOptions creationOptions,
215                                                         TaskScheduler scheduler)
216                 {
217                         var t = new Task<TResult> (function, state, cancellationToken, creationOptions);
218                         
219                         //
220                         // Don't start cancelled task it would throw an exception
221                         //
222                         if (!t.IsCompleted)
223                                 t.Start (scheduler);
224
225                         return t;
226                 }
227                 #endregion
228                 
229                 #region Continue
230                 
231                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction)
232                 {
233                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
234                 }
235                 
236                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken)
237                 {
238                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
239                 }
240                 
241                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
242                 {
243                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
244                 }
245
246                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
247                 {
248                         CheckContinueArguments (tasks, continuationAction, continuationOptions, scheduler);
249
250                         var cont = Task.WhenAnyCore (tasks).ContinueWith (TaskActionInvoker.CreateSelected (continuationAction), cancellationToken, continuationOptions, scheduler);
251
252                         return cont;
253                 }
254                 
255                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
256                                                                 Action<Task<TAntecedentResult>> continuationAction)
257                 {
258                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
259                 }
260                 
261                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
262                                                                 Action<Task<TAntecedentResult>> continuationAction,
263                                                                 CancellationToken cancellationToken)
264                 {
265                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
266                 }
267                 
268                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
269                                                                 Action<Task<TAntecedentResult>> continuationAction,
270                                                                 TaskContinuationOptions continuationOptions)
271                 {
272                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
273                 }
274
275                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
276                                                                 Action<Task<TAntecedentResult>> continuationAction,
277                                                                 CancellationToken cancellationToken,
278                                                                 TaskContinuationOptions continuationOptions,
279                                                                 TaskScheduler scheduler)
280                 {
281                         return ContinueWhenAny ((Task[]) tasks,
282                                                 (o) => continuationAction ((Task<TAntecedentResult>)o),
283                                                 cancellationToken, continuationOptions, scheduler);
284                 }
285
286                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationFunction)
287                 {
288                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
289                 }
290
291                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
292                                                                Func<Task, TResult> continuationFunction,
293                                                                CancellationToken cancellationToken)
294                 {
295                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
296                 }
297
298                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
299                                                                Func<Task, TResult> continuationFunction,
300                                                                TaskContinuationOptions continuationOptions)
301                 {
302                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
303                 }
304
305                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
306                                                                Func<Task, TResult> continuationFunction,
307                                                                CancellationToken cancellationToken,
308                                                                TaskContinuationOptions continuationOptions,
309                                                                TaskScheduler scheduler)
310                 {
311                         CheckContinueArguments (tasks, continuationFunction, continuationOptions, scheduler);
312
313                         var cont = Task.WhenAnyCore (tasks).ContinueWith<TResult> (TaskActionInvoker.CreateSelected (continuationFunction), cancellationToken, continuationOptions, scheduler);
314
315                         return cont;
316                 }
317
318                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
319                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction)
320                 {
321                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
322                 }
323
324                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
325                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction,
326                                                                                   CancellationToken cancellationToken)
327                 {
328                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
329                 }
330
331                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
332                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction,
333                                                                                   TaskContinuationOptions continuationOptions)
334                 {
335                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
336                 }
337
338                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
339                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction,
340                                                                                   CancellationToken cancellationToken,
341                                                                                   TaskContinuationOptions continuationOptions,
342                                                                                   TaskScheduler scheduler)
343                 {
344                         return ContinueWhenAny<TResult> ((Task[])tasks,
345                                                          (t) => continuationFunction((Task<TAntecedentResult>)t),
346                                                          cancellationToken,
347                                                          continuationOptions,
348                                                          scheduler);
349                 }
350                 
351                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction)
352                 {
353                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
354                 }
355                 
356                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken)
357                 {
358                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
359                 }
360                 
361                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction,
362                                              TaskContinuationOptions continuationOptions)
363                 {
364                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
365                 }
366                 
367                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
368                                              TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
369                 {
370                         CheckContinueArguments (tasks, continuationAction, continuationOptions, scheduler);
371
372                         var cont = Task.WhenAllCore (tasks).ContinueWith (TaskActionInvoker.Create (continuationAction, tasks), cancellationToken, continuationOptions, scheduler);
373
374                         return cont;
375                 }
376                 
377                 public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
378                                                                 Action<Task<TAntecedentResult>[]> continuationAction)
379                 {
380                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
381                 }
382                 
383                 public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
384                                                                 Action<Task<TAntecedentResult>[]> continuationAction, CancellationToken cancellationToken)
385                 {
386                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
387                 }
388                 
389                 public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
390                                                                 TaskContinuationOptions continuationOptions)
391                 {
392                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
393                 }
394                 
395                 public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks, 
396                                                                 Action<Task<TAntecedentResult>[]> continuationAction,
397                                                                 CancellationToken cancellationToken, TaskContinuationOptions continuationOptions,
398                                                                 TaskScheduler scheduler)
399                 {
400                         return ContinueWhenAll ((Task[]) tasks, (o) => continuationAction (tasks), cancellationToken,
401                                                 continuationOptions, scheduler);
402                 }
403                 
404                 public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction)
405                 {
406                         return ContinueWhenAll<TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
407                 }
408                 
409                 public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction,
410                                                                TaskContinuationOptions continuationOptions)
411                 {
412                         return ContinueWhenAll<TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
413                 }
414                 
415                 public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction,
416                                                                CancellationToken cancellationToken)
417                 {
418                         return ContinueWhenAll<TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
419                 }
420                 
421                 public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction,
422                                                                CancellationToken cancellationToken,
423                                                                TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
424                 {
425                         CheckContinueArguments (tasks, continuationFunction, continuationOptions, scheduler);
426
427                         var cont = Task.WhenAllCore (tasks).ContinueWith<TResult> (TaskActionInvoker.Create (continuationFunction, tasks), cancellationToken, continuationOptions, scheduler);
428
429                         return cont;
430                 }
431                 
432                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
433                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction)
434                 {
435                         return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
436                 }
437                 
438                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks, 
439                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction,
440                                                                                   TaskContinuationOptions continuationOptions)
441                 {
442                         return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
443                 }
444                 
445                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
446                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction,
447                                                                                   CancellationToken cancellationToken)
448                 {
449                         return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
450                 }
451                 
452                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks, 
453                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction,
454                                                                                   CancellationToken cancellationToken,
455                                                                                   TaskContinuationOptions continuationOptions,
456                                                                                   TaskScheduler scheduler)
457                 {
458                         return ContinueWhenAll<TResult> ((Task[]) tasks,
459                                                          (o) => continuationFunction (tasks),
460                                                          cancellationToken,
461                                                          continuationOptions, scheduler);
462                 }
463
464                 #endregion
465
466                 #region FromAsync IAsyncResult
467                 
468                 public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod)
469                 {
470                         return FromAsync (asyncResult, endMethod, creationOptions);
471                 }
472                 
473                 public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod, TaskCreationOptions creationOptions)
474                 {
475                         return FromAsync (asyncResult, endMethod, creationOptions, GetScheduler ());
476                 }
477
478                 public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
479                 {
480                         if (endMethod == null)
481                                 throw new ArgumentNullException ("endMethod");
482
483                         return TaskFactory<object>.FromIAsyncResult (asyncResult,
484                                 l => {
485                                         endMethod (asyncResult);
486                                         return null;
487                                 }, creationOptions, scheduler);
488                 }
489                 
490                 public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
491                 {
492                         return FromAsync<TResult> (asyncResult, endMethod, creationOptions);
493                 }
494                 
495                 public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions)
496                 {
497                         return FromAsync<TResult> (asyncResult, endMethod, creationOptions, GetScheduler ());
498                 }
499                 
500                 public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
501                 {
502                         return TaskFactory<TResult>.FromIAsyncResult (asyncResult, endMethod, creationOptions, scheduler);
503                 }
504
505                 #endregion
506
507                 #region FromAsync Begin/End Method
508
509                 public Task FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, object state)
510                 {
511                         return FromAsync (beginMethod, endMethod, state, creationOptions);
512                 }
513
514                 public Task FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
515                                                            object state, TaskCreationOptions creationOptions)
516                 {
517                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
518                                 l => { endMethod (l); return null; },
519                                 state, creationOptions);
520                 }
521
522                 public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
523                                                   TArg1 arg1, object state)
524                 {
525                         return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
526                 }
527
528                 public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
529                                               TArg1 arg1, object state, TaskCreationOptions creationOptions)
530                 {
531                         if (endMethod == null)
532                                 throw new ArgumentNullException ("endMethod");
533
534                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
535                                 l => { endMethod (l); return null; },
536                                 arg1, state, creationOptions);
537                 }
538
539                 public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
540                                                      Action<IAsyncResult> endMethod,
541                                                      TArg1 arg1, TArg2 arg2, object state)
542                 {
543                         return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
544                 }
545
546                 public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
547                                                      Action<IAsyncResult> endMethod,
548                                                      TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
549                 {
550                         if (endMethod == null)
551                                 throw new ArgumentNullException ("endMethod");
552
553                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
554                                 l => { endMethod (l); return null; },
555                                 arg1, arg2, state, creationOptions);
556                 }
557
558                 public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
559                                                             TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
560                 {
561                         return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
562                 }
563
564                 public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
565                                                             TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
566                 {
567                         if (endMethod == null)
568                                 throw new ArgumentNullException ("endMethod");
569
570                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
571                                 l => { endMethod (l); return null; },
572                                 arg1, arg2, arg3, state, creationOptions);
573                 }
574
575                 public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
576                                                          object state)
577                 {
578                         return FromAsync (beginMethod, endMethod, state, creationOptions);
579                 }
580
581                 public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
582                                                          object state, TaskCreationOptions creationOptions)
583                 {
584                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, state, creationOptions);
585                 }
586
587                 public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
588                                                                 TArg1 arg1, object state)
589                 {
590                         return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
591                 }
592
593                 public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
594                                                                 TArg1 arg1, object state, TaskCreationOptions creationOptions)
595                 {
596                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, state, creationOptions);
597                 }
598
599                 public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
600                                                                        Func<IAsyncResult, TResult> endMethod,
601                                                                        TArg1 arg1, TArg2 arg2, object state)
602                 {
603                         return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
604                 }
605
606                 public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
607                                                                        TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
608                 {
609                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, state, creationOptions);
610                 }
611
612                 public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
613                                                                               TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
614                 {
615                         return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
616                 }
617
618                 public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
619                                                                               TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
620                 {
621                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
622                 }
623
624                 #endregion
625
626                 TaskScheduler GetScheduler ()
627                 {
628                         return scheduler ?? TaskScheduler.Current;
629                 }
630
631                 static void CheckContinueArguments (Task[] tasks, object continuationAction, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
632                 {
633                         if (tasks == null)
634                                 throw new ArgumentNullException ("tasks");
635
636                         if (tasks.Length == 0)
637                                 throw new ArgumentException ("The tasks argument contains no tasks", "tasks");
638
639                         foreach (var ta in tasks) {
640                                 if (ta == null)
641                                         throw new ArgumentException ("The tasks argument contains a null value", "tasks");
642                         }
643
644                         if (continuationAction == null)
645                                 throw new ArgumentNullException ("continuationAction");
646                         if (scheduler == null)
647                                 throw new ArgumentNullException ("scheduler");
648
649                         const TaskContinuationOptions notAllowedOptions = 
650                                 TaskContinuationOptions.NotOnRanToCompletion  |
651                                 TaskContinuationOptions.NotOnFaulted |
652                                 TaskContinuationOptions.NotOnCanceled |
653                                 TaskContinuationOptions.OnlyOnRanToCompletion |
654                                 TaskContinuationOptions.OnlyOnFaulted |
655                                 TaskContinuationOptions.OnlyOnCanceled;
656
657                         if ((continuationOptions & notAllowedOptions) != 0)
658                                 throw new ArgumentOutOfRangeException ("continuationOptions");
659                 }
660         }
661 }
662 #endif