Merge pull request #167 from konrad-kruczynski/send_async_fix
[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 || MOBILE
30
31 using System;
32 using System.Threading;
33
34 namespace System.Threading.Tasks
35 {
36         
37         public class TaskFactory
38         {
39                 readonly TaskScheduler scheduler;
40                 TaskCreationOptions creationOptions;
41                 TaskContinuationOptions continuationOptions;
42                 CancellationToken cancellationToken;
43                 
44                 public TaskFactory ()
45                         : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, null)
46                 {
47                 }
48
49                 public TaskFactory (CancellationToken cancellationToken)
50                         : this (cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
51                 {       
52                 }
53
54                 public TaskFactory (TaskScheduler scheduler)
55                         : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler)
56                 {       
57                 }
58                 
59                 public TaskFactory (TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
60                         : this (CancellationToken.None, creationOptions, continuationOptions, null)
61                 {       
62                 }
63                 
64                 public TaskFactory (CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions,
65                                     TaskScheduler scheduler)
66                 {
67                         this.cancellationToken = cancellationToken;
68                         this.scheduler = scheduler;
69                         this.creationOptions = creationOptions;
70                         this.continuationOptions = continuationOptions;
71
72                         CheckContinuationOptions (continuationOptions);
73                 }
74                 
75                 public TaskScheduler Scheduler {
76                         get {
77                                 return scheduler;
78                         }
79                 }
80                 
81                 public TaskContinuationOptions ContinuationOptions {
82                         get {
83                                 return continuationOptions;
84                         }
85                 }
86                 
87                 public TaskCreationOptions CreationOptions {
88                         get {
89                                 return creationOptions;
90                         }
91                 }
92                 
93                 public CancellationToken CancellationToken {
94                         get {
95                                 return cancellationToken;
96                         }
97                 }
98
99                 internal static void CheckContinuationOptions (TaskContinuationOptions continuationOptions)
100                 {
101                         if ((continuationOptions & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) != 0)
102                                 throw new ArgumentOutOfRangeException ("continuationOptions");
103
104                         const TaskContinuationOptions long_running = TaskContinuationOptions.LongRunning | TaskContinuationOptions.ExecuteSynchronously;
105                         if ((continuationOptions & long_running) == long_running)
106                                 throw new ArgumentOutOfRangeException ("continuationOptions", "Synchronous continuations cannot be long running");
107                 }
108                 
109                 #region StartNew for Task
110                 public Task StartNew (Action action)
111                 {
112                         return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
113                 }
114                 
115                 public Task StartNew (Action action, CancellationToken cancellationToken)
116                 {
117                         return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
118                 }
119                 
120                 public Task StartNew (Action action, TaskCreationOptions creationOptions)
121                 {
122                         return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
123                 }
124                 
125                 public Task StartNew (Action<object> action, object state)
126                 {
127                         return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
128                 }
129                 
130                 public Task StartNew (Action<object> action, object state, CancellationToken cancellationToken)
131                 {
132                         return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
133                 }
134                 
135                 public Task StartNew (Action<object> action, object state, TaskCreationOptions creationOptions)
136                 {
137                         return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
138                 }
139                 
140                 public Task StartNew (Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
141                 {
142                         Task t = new Task (action, cancellationToken, creationOptions);
143                         t.Start (scheduler);
144
145                         return t;
146                 }
147                 
148                 public Task StartNew (Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions,
149                                       TaskScheduler scheduler)
150                 {
151                         Task t = new Task (action, state, cancellationToken, creationOptions);
152                         t.Start (scheduler);
153                         
154                         return t;
155                 }
156                 #endregion
157                 
158                 #region StartNew for Task<TResult>      
159                 public Task<TResult> StartNew<TResult> (Func<TResult> function)
160                 {
161                         return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
162                 }
163                 
164                 public Task<TResult> StartNew<TResult> (Func<TResult> function, TaskCreationOptions creationOptions)
165                 {
166                         return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
167
168                 }
169                 
170                 public Task<TResult> StartNew<TResult> (Func<TResult> function, CancellationToken cancellationToken)
171                 {
172                         return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
173                 }
174                 
175                 public Task<TResult> StartNew<TResult> (Func<TResult> function,
176                                                         CancellationToken cancellationToken,
177                                                         TaskCreationOptions creationOptions,
178                                                         TaskScheduler scheduler)
179                 {
180                         return StartNew<TResult> ((o) => function (), null, cancellationToken, creationOptions, scheduler);
181                 }
182                 
183                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state)
184                 {
185                         return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
186                 }
187                 
188                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, CancellationToken cancellationToken)
189                 {
190                         return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
191                 }
192                 
193                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
194                 {
195                         return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
196                 }
197                 
198                 public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state,
199                                                         CancellationToken cancellationToken,
200                                                         TaskCreationOptions creationOptions,
201                                                         TaskScheduler scheduler)
202                 {
203                         Task<TResult> t = new Task<TResult> (function, state, cancellationToken, creationOptions);
204                         t.Start (scheduler);
205                         
206                         return t;
207                 }
208                 #endregion
209                 
210                 #region Continue
211                 
212                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction)
213                 {
214                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
215                 }
216                 
217                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken)
218                 {
219                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
220                 }
221                 
222                 public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
223                 {
224                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
225                 }
226
227                 public Task ContinueWhenAny (Task[] tasks,
228                                              Action<Task> continuationAction,
229                                              CancellationToken cancellationToken,
230                                              TaskContinuationOptions continuationOptions,
231                                              TaskScheduler scheduler)
232                 {
233                         var ourTasks = (Task[])tasks.Clone ();
234                         AtomicBoolean trigger = new AtomicBoolean ();
235                         var commonContinuation = new TaskCompletionSource<object> ();
236                         Action<Task> continuationFunc = t => commonContinuation.SetResult (null);
237                         
238                         foreach (Task t in ourTasks) {
239                                 Task cont = new Task ((o) => continuationAction ((Task)o), t, cancellationToken, creationOptions, t);
240                                 t.ContinueWithCore (cont, continuationOptions, scheduler, trigger.TrySet);
241                                 cont.ContinueWith (continuationFunc);
242                         }
243                         
244                         return commonContinuation.Task;
245                 }
246                 
247                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
248                                                                 Action<Task<TAntecedentResult>> continuationAction)
249                 {
250                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
251                 }
252                 
253                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
254                                                                 Action<Task<TAntecedentResult>> continuationAction,
255                                                                 CancellationToken cancellationToken)
256                 {
257                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
258                 }
259                 
260                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
261                                                                 Action<Task<TAntecedentResult>> continuationAction,
262                                                                 TaskContinuationOptions continuationOptions)
263                 {
264                         return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
265                 }
266
267                 public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
268                                                                 Action<Task<TAntecedentResult>> continuationAction,
269                                                                 CancellationToken cancellationToken,
270                                                                 TaskContinuationOptions continuationOptions,
271                                                                 TaskScheduler scheduler)
272                 {
273                         return ContinueWhenAny ((Task[]) tasks,
274                                                 (o) => continuationAction ((Task<TAntecedentResult>)o),
275                                                 cancellationToken, continuationOptions, scheduler);
276                 }
277
278                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationFunction)
279                 {
280                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
281                 }
282
283                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
284                                                                Func<Task, TResult> continuationFunction,
285                                                                CancellationToken cancellationToken)
286                 {
287                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
288                 }
289
290                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
291                                                                Func<Task, TResult> continuationFunction,
292                                                                TaskContinuationOptions continuationOptions)
293                 {
294                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
295                 }
296
297                 public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
298                                                                Func<Task, TResult> continuationFunction,
299                                                                CancellationToken cancellationToken,
300                                                                TaskContinuationOptions continuationOptions,
301                                                                TaskScheduler scheduler)
302                 {
303                         var ourTasks = (Task[])tasks.Clone ();
304                         AtomicBoolean trigger = new AtomicBoolean ();
305                         TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult> ();
306
307                         foreach (Task t in ourTasks) {
308                                 Task cont = new Task ((o) => source.SetResult (continuationFunction ((Task)o)), t, cancellationToken, creationOptions, t);
309                                 t.ContinueWithCore (cont, continuationOptions, scheduler, trigger.TrySet);
310                         }
311
312                         return source.Task;
313                 }
314
315                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
316                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction)
317                 {
318                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
319                 }
320
321                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
322                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction,
323                                                                                   CancellationToken cancellationToken)
324                 {
325                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
326                 }
327
328                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
329                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction,
330                                                                                   TaskContinuationOptions continuationOptions)
331                 {
332                         return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
333                 }
334
335                 public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
336                                                                                   Func<Task<TAntecedentResult>, TResult> continuationFunction,
337                                                                                   CancellationToken cancellationToken,
338                                                                                   TaskContinuationOptions continuationOptions,
339                                                                                   TaskScheduler scheduler)
340                 {
341                         return ContinueWhenAny<TResult> ((Task[])tasks,
342                                                          (t) => continuationFunction((Task<TAntecedentResult>)t),
343                                                          cancellationToken,
344                                                          continuationOptions,
345                                                          scheduler);
346                 }
347                 
348                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction)
349                 {
350                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
351                 }
352                 
353                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken)
354                 {
355                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
356                 }
357                 
358                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction,
359                                              TaskContinuationOptions continuationOptions)
360                 {
361                         return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
362                 }
363                 
364                 public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
365                                              TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
366                 {
367                         var ourTasks = (Task[])tasks.Clone ();
368                         CountdownEvent evt = new CountdownEvent (ourTasks.Length);
369                         Task cont = new Task ((o) => continuationAction ((Task[])o), ourTasks, cancellationToken, creationOptions);
370                         
371                         foreach (Task t in ourTasks)
372                                 t.ContinueWithCore (cont, continuationOptions, scheduler, evt.Signal);
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                         var ourTasks = (Task[])tasks.Clone ();
426                         CountdownEvent evt = new CountdownEvent (ourTasks.Length);
427                         Task<TResult> cont = new Task<TResult> ((o) => continuationFunction ((Task[])o), ourTasks, cancellationToken, creationOptions);
428                         
429                         foreach (Task t in ourTasks)
430                                 t.ContinueWithCore (cont, continuationOptions, scheduler, evt.Signal);
431                         
432                         return cont;
433                 }
434                 
435                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
436                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction)
437                 {
438                         return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
439                 }
440                 
441                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks, 
442                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction,
443                                                                                   TaskContinuationOptions continuationOptions)
444                 {
445                         return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
446                 }
447                 
448                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
449                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction,
450                                                                                   CancellationToken cancellationToken)
451                 {
452                         return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
453                 }
454                 
455                 public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks, 
456                                                                                   Func<Task<TAntecedentResult>[], TResult> continuationFunction,
457                                                                                   CancellationToken cancellationToken,
458                                                                                   TaskContinuationOptions continuationOptions,
459                                                                                   TaskScheduler scheduler)
460                 {
461                         return ContinueWhenAll<TResult> ((Task[]) tasks,
462                                                          (o) => continuationFunction (tasks),
463                                                          cancellationToken,
464                                                          continuationOptions, scheduler);
465                 }
466
467                 #endregion
468
469                 #region FromAsync IAsyncResult
470                 
471                 public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod)
472                 {
473                         return FromAsync (asyncResult, endMethod, creationOptions);
474                 }
475                 
476                 public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod, TaskCreationOptions creationOptions)
477                 {
478                         return FromAsync (asyncResult, endMethod, creationOptions, GetScheduler ());
479                 }
480
481                 public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
482                 {
483                         if (endMethod == null)
484                                 throw new ArgumentNullException ("endMethod");
485
486                         return TaskFactory<object>.FromIAsyncResult (asyncResult,
487                                 l => {
488                                         endMethod (asyncResult);
489                                         return null;
490                                 }, creationOptions, scheduler);
491                 }
492                 
493                 public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
494                 {
495                         return FromAsync<TResult> (asyncResult, endMethod, creationOptions);
496                 }
497                 
498                 public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions)
499                 {
500                         return FromAsync<TResult> (asyncResult, endMethod, creationOptions, GetScheduler ());
501                 }
502                 
503                 public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
504                 {
505                         return TaskFactory<TResult>.FromIAsyncResult (asyncResult, endMethod, creationOptions, scheduler);
506                 }
507
508                 #endregion
509
510                 #region FromAsync Begin/End Method
511
512                 public Task FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, object state)
513                 {
514                         return FromAsync (beginMethod, endMethod, state, creationOptions);
515                 }
516
517                 public Task FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
518                                                            object state, TaskCreationOptions creationOptions)
519                 {
520                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
521                                 l => { endMethod (l); return null; },
522                                 state, creationOptions);
523                 }
524
525                 public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
526                                                   TArg1 arg1, object state)
527                 {
528                         return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
529                 }
530
531                 public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
532                                               TArg1 arg1, object state, TaskCreationOptions creationOptions)
533                 {
534                         if (endMethod == null)
535                                 throw new ArgumentNullException ("endMethod");
536
537                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
538                                 l => { endMethod (l); return null; },
539                                 arg1, state, creationOptions);
540                 }
541
542                 public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
543                                                      Action<IAsyncResult> endMethod,
544                                                      TArg1 arg1, TArg2 arg2, object state)
545                 {
546                         return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
547                 }
548
549                 public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
550                                                      Action<IAsyncResult> endMethod,
551                                                      TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
552                 {
553                         if (endMethod == null)
554                                 throw new ArgumentNullException ("endMethod");
555
556                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
557                                 l => { endMethod (l); return null; },
558                                 arg1, arg2, state, creationOptions);
559                 }
560
561                 public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
562                                                             TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
563                 {
564                         return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
565                 }
566
567                 public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
568                                                             TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
569                 {
570                         if (endMethod == null)
571                                 throw new ArgumentNullException ("endMethod");
572
573                         return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
574                                 l => { endMethod (l); return null; },
575                                 arg1, arg2, arg3, state, creationOptions);
576                 }
577
578                 public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
579                                                          object state)
580                 {
581                         return FromAsync (beginMethod, endMethod, state, creationOptions);
582                 }
583
584                 public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
585                                                          object state, TaskCreationOptions creationOptions)
586                 {
587                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, state, creationOptions);
588                 }
589
590                 public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
591                                                                 TArg1 arg1, object state)
592                 {
593                         return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
594                 }
595
596                 public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
597                                                                 TArg1 arg1, object state, TaskCreationOptions creationOptions)
598                 {
599                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, state, creationOptions);
600                 }
601
602                 public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
603                                                                        Func<IAsyncResult, TResult> endMethod,
604                                                                        TArg1 arg1, TArg2 arg2, object state)
605                 {
606                         return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
607                 }
608
609                 public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
610                                                                        TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
611                 {
612                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, state, creationOptions);
613                 }
614
615                 public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
616                                                                               TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
617                 {
618                         return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
619                 }
620
621                 public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
622                                                                               TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
623                 {
624                         return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
625                 }
626
627                 #endregion
628
629                 TaskScheduler GetScheduler ()
630                 {
631                         return scheduler ?? TaskScheduler.Current;
632                 }
633         }
634 }
635 #endif