Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / class / corlib / System.Threading.Tasks / TaskFactory_T.cs
index bcc8a36187384f65d4bcbcfa302b099e9339570b..0ac088c9058160dc52cc14bbc0d73ca6d066ea2c 100644 (file)
@@ -1,10 +1,12 @@
 // 
 // TaskFactory_T.cs
 //  
-// Author:
+// Authors:
 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
+//       Marek Safar <marek.safar@gmail.com>
 // 
 // Copyright (c) 2009 Jérémie "Garuma" Laval
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
 // 
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 
 #if NET_4_0 || MOBILE
 
-using System;
-using System.Threading;
-
 namespace System.Threading.Tasks
 {
        public class TaskFactory<TResult>
        {
-               TaskScheduler scheduler;
+               readonly TaskScheduler scheduler;
                TaskCreationOptions creationOptions;
                TaskContinuationOptions continuationOptions;
                CancellationToken cancellationToken;
                
                TaskFactory parent;
-               
-               #region ctors
+
                public TaskFactory ()
-                       : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Current)
+                       : this (CancellationToken.None)
                {       
                }
                
@@ -52,42 +50,65 @@ namespace System.Threading.Tasks
                }
                
                public TaskFactory (CancellationToken cancellationToken)
-                       : this (cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Current)
+                       : this (cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
                {       
                }
                
                public TaskFactory (TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
-                       : this (CancellationToken.None, creationOptions, continuationOptions, TaskScheduler.Current)
+                       : this (CancellationToken.None, creationOptions, continuationOptions, null)
                {       
                }
                
-               public TaskFactory (CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions,
-                                   TaskScheduler scheduler)
+               public TaskFactory (CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
                {
                        this.cancellationToken = cancellationToken;
                        this.scheduler = scheduler;
                        this.creationOptions = creationOptions;
                        this.continuationOptions = continuationOptions;
+
+                       TaskFactory.CheckContinuationOptions (continuationOptions);
                        
                        this.parent = new TaskFactory (cancellationToken, creationOptions, continuationOptions, scheduler);
                }
+
+               public TaskScheduler Scheduler {
+                       get {
+                               return scheduler;
+                       }
+               }
                
-               #endregion
+               public TaskContinuationOptions ContinuationOptions {
+                       get {
+                               return continuationOptions;
+                       }
+               }
+               
+               public TaskCreationOptions CreationOptions {
+                       get {
+                               return creationOptions;
+                       }
+               }
+               
+               public CancellationToken CancellationToken {
+                       get {
+                               return cancellationToken;
+                       }
+               }
                
                #region StartNew for Task<TResult>      
                public Task<TResult> StartNew (Func<TResult> function)
                {
-                       return StartNew (function, cancellationToken, creationOptions, scheduler);
+                       return StartNew (function, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew (Func<TResult> function, TaskCreationOptions creationOptions)
                {
-                       return StartNew (function, cancellationToken, creationOptions, scheduler);
+                       return StartNew (function, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew (Func<TResult> function, CancellationToken cancellationToken)
                {
-                       return StartNew (function, cancellationToken, creationOptions, scheduler);
+                       return StartNew (function, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew (Func<TResult> function, 
@@ -100,17 +121,17 @@ namespace System.Threading.Tasks
                
                public Task<TResult> StartNew (Func<object, TResult> function, object state)
                {
-                       return StartNew (function, state, cancellationToken, creationOptions, scheduler);
+                       return StartNew (function, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
                {
-                       return StartNew (function, state, cancellationToken, creationOptions, scheduler);
+                       return StartNew (function, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew (Func<object, TResult> function, object state, CancellationToken cancellationToken)
                {
-                       return StartNew (function, state, cancellationToken, creationOptions, scheduler);
+                       return StartNew (function, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew (Func<object, TResult> function, object state, 
@@ -127,21 +148,21 @@ namespace System.Threading.Tasks
                public Task<TResult> ContinueWhenAny (Task[] tasks,
                                                      Func<Task, TResult> continuationFunction)
                {
-                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
                public Task<TResult> ContinueWhenAny (Task[] tasks,
                                                      Func<Task, TResult> continuationFunction,
                                                      CancellationToken cancellationToken)
                {
-                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
                public Task<TResult> ContinueWhenAny (Task[] tasks,
                                                      Func<Task, TResult> continuationFunction,
                                                      TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
                public Task<TResult> ContinueWhenAny (Task[] tasks,
@@ -156,21 +177,21 @@ namespace System.Threading.Tasks
                public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
                                                                         Func<Task<TAntecedentResult>, TResult> continuationFunction)
                {
-                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
                public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
                                                                         Func<Task<TAntecedentResult>, TResult> continuationFunction,
                                                                         CancellationToken cancellationToken)
                {
-                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
                public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
                                                                         Func<Task<TAntecedentResult>, TResult> continuationFunction,
                                                                         TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
                public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
@@ -182,24 +203,23 @@ namespace System.Threading.Tasks
                        return parent.ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
                }
                
-               public Task<TResult> ContinueWhenAll (Task[] tasks,
-                                                     Func<Task[], TResult> continuationFunction)
+               public Task<TResult> ContinueWhenAll (Task[] tasks, Func<Task[], TResult> continuationFunction)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll (Task[] tasks,
                                                      Func<Task[], TResult> continuationFunction,
                                                      TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll (Task[] tasks,
                                                      Func<Task[], TResult> continuationFunction,
                                                      CancellationToken cancellationToken)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll (Task[] tasks,
@@ -213,21 +233,21 @@ namespace System.Threading.Tasks
                public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
                                                                         Func<Task<TAntecedentResult>[], TResult> continuationFunction)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
                                                                         Func<Task<TAntecedentResult>[], TResult> continuationFunction,
                                                                         TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
                                                                         Func<Task<TAntecedentResult>[], TResult> continuationFunction,
                                                                         CancellationToken cancellationToken)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
@@ -241,115 +261,220 @@ namespace System.Threading.Tasks
                #endregion
                
                #region FromAsync
-               const string errorMsg = "Mono's thread pool doesn't support this operation yet";
                
-               [MonoLimitation(errorMsg)]
                public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
                {
                        return FromAsync (asyncResult, endMethod, creationOptions);
                }
                
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod,
-                                               TaskCreationOptions creationOptions)
+               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions)
                {
-                       return FromAsync (asyncResult, endMethod, creationOptions);
+                       return FromAsync (asyncResult, endMethod, creationOptions, GetScheduler ());
                }
                
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod,
-                                               TaskCreationOptions creationOptions, TaskScheduler scheduler)
+               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromIAsyncResult (asyncResult, endMethod, creationOptions, scheduler);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (Func<AsyncCallback, Object, IAsyncResult> beginMethod,
-                                               Func<IAsyncResult, TResult> endMethod,
+
+               internal static Task<TResult> FromIAsyncResult (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+               {
+                       if (asyncResult == null)
+                           throw new ArgumentNullException ("asyncResult");
+
+                       if (endMethod == null)
+                           throw new ArgumentNullException ("endMethod");
+
+                       if (scheduler == null)
+                               throw new ArgumentNullException ("scheduler");
+
+                       if ((creationOptions & Task.WorkerTaskNotSupportedOptions) != 0)
+                               throw new ArgumentOutOfRangeException ("creationOptions");
+
+                       var source = new CancellationTokenSource ();
+                       var task = new Task<TResult> (l => {
+                               try {
+                                       return endMethod (asyncResult);
+                               } catch (OperationCanceledException) {
+                                       source.Cancel ();
+                                       source.Token.ThrowIfCancellationRequested ();
+                               }
+                               return default (TResult);
+                       }, null, source.Token, creationOptions);
+
+                       // Take quick path for completed operations
+                       if (asyncResult.IsCompleted) {
+                               task.RunSynchronously (scheduler);
+                       } else {
+                               ThreadPool.RegisterWaitForSingleObject (asyncResult.AsyncWaitHandle,
+                                                                       (s, t) => task.RunSynchronously (scheduler),
+                                                                       null, Timeout.Infinite, true);
+                       }
+
+                       return task;
+               }
+
+               public Task<TResult> FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (Func<AsyncCallback, Object, IAsyncResult> beginMethod,
-                                               Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsyncBeginEnd (beginMethod, endMethod, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                      Func<IAsyncResult, TResult> endMethod,
+
+               internal static Task<TResult> FromAsyncBeginEnd (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
+                                                                object state, TaskCreationOptions creationOptions)
+               {
+                       if (beginMethod == null)
+                               throw new ArgumentNullException ("beginMethod");
+
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       if ((creationOptions & Task.WorkerTaskNotSupportedOptions) != 0)
+                               throw new ArgumentOutOfRangeException ("creationOptions");
+
+                       var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
+                       var alreadyInvoked = new AtomicBoolean ();
+                       var iar = beginMethod (l => {
+                               if (alreadyInvoked.TryRelaxedSet ())
+                                       InnerInvoke (tcs, endMethod, l);
+                       }, state);
+                       if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ())
+                               InnerInvoke (tcs, endMethod, iar);
+
+                       return tcs.Task;
+               }
+
+               public Task<TResult> FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                       TArg1 arg1, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                      Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                       TArg1 arg1, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsyncBeginEnd (beginMethod, endMethod, arg1, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                             Func<IAsyncResult, TResult> endMethod,
+
+               internal static Task<TResult> FromAsyncBeginEnd<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
+                                                                       Func<IAsyncResult, TResult> endMethod,
+                                                                       TArg1 arg1, object state, TaskCreationOptions creationOptions)
+               {
+                       if (beginMethod == null)
+                               throw new ArgumentNullException ("beginMethod");
+
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       if ((creationOptions & Task.WorkerTaskNotSupportedOptions) != 0)
+                               throw new ArgumentOutOfRangeException ("creationOptions");
+
+                       var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
+                       var alreadyInvoked = new AtomicBoolean ();
+                       var iar = beginMethod (arg1, l => {
+                               if (alreadyInvoked.TryRelaxedSet ())
+                                       InnerInvoke (tcs, endMethod, l);
+                       }, state);
+                       if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ())
+                               InnerInvoke (tcs, endMethod, iar);
+
+                       return tcs.Task;
+               }
+
+               public Task<TResult> FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                              TArg1 arg1, TArg2 arg2, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                             Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                              TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                    Func<IAsyncResult, TResult> endMethod,
+
+               internal static Task<TResult> FromAsyncBeginEnd<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
+                                                                                 TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
+               {
+                       if (beginMethod == null)
+                               throw new ArgumentNullException ("beginMethod");
+
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       if ((creationOptions & Task.WorkerTaskNotSupportedOptions) != 0)
+                               throw new ArgumentOutOfRangeException ("creationOptions");
+
+                       var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
+                       var alreadyInvoked = new AtomicBoolean ();
+                       var iar = beginMethod (arg1, arg2, l => {
+                               if (alreadyInvoked.TryRelaxedSet ())
+                                       InnerInvoke (tcs, endMethod, l);
+                       }, state);
+                       if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ())
+                               InnerInvoke (tcs, endMethod, iar);
+
+                       return tcs.Task;
+               }
+
+               public Task<TResult> FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                                     TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                    Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                                     TArg1 arg1, TArg2 arg2, TArg3 arg3, object state,
                                                                     TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
-               }
-               #endregion
-               
-               public TaskScheduler Scheduler {
-                       get {
-                               return scheduler;
-                       }
+                       return FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
                }
-               
-               public TaskContinuationOptions ContinuationOptions {
-                       get {
-                               return continuationOptions;
-                       }
+
+               internal static Task<TResult> FromAsyncBeginEnd<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
+                                                                                 TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
+               {
+                       if (beginMethod == null)
+                               throw new ArgumentNullException ("beginMethod");
+
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       if ((creationOptions & Task.WorkerTaskNotSupportedOptions) != 0)
+                               throw new ArgumentOutOfRangeException ("creationOptions");
+
+                       var tcs = new TaskCompletionSource<TResult> (state, creationOptions);
+                       var alreadyInvoked = new AtomicBoolean ();
+                       var iar = beginMethod (arg1, arg2, arg3, l => {
+                               if (alreadyInvoked.TryRelaxedSet ())
+                                       InnerInvoke (tcs, endMethod, l);
+                       }, state);
+                       if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ())
+                               InnerInvoke (tcs, endMethod, iar);
+
+                       return tcs.Task;
                }
-               
-               public TaskCreationOptions CreationOptions {
-                       get {
-                               return creationOptions;
-                       }
+
+               #endregion
+
+               TaskScheduler GetScheduler ()
+               {
+                       return scheduler ?? TaskScheduler.Current;
                }
-               
-               public CancellationToken CancellationToken {
-                       get {
-                               return cancellationToken;
+
+               static void InnerInvoke (TaskCompletionSource<TResult> tcs, Func<IAsyncResult, TResult> endMethod, IAsyncResult l)
+               {
+                       try {
+                               tcs.SetResult (endMethod (l));
+                       } catch (OperationCanceledException) {
+                               tcs.SetCanceled ();
+                       } catch (Exception e) {
+                               tcs.SetException (e);
                        }
                }
        }