消除各种编译警告
智能大石头 authored at 2023-03-08 21:47:28
36.79 KiB
X_NET20
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;

namespace System.Threading.Tasks
{
	[DebuggerDisplay("Id = {Id}, Status = {Status}")]
	[DebuggerTypeProxy(typeof(TaskDebuggerView))]
	public class Task : IDisposable, IAsyncResult
	{
		internal const TaskCreationOptions WorkerTaskNotSupportedOptions = TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning;

		private const TaskCreationOptions MaxTaskCreationOptions = TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler;

		[ThreadStatic]
		private static Task current;

		[ThreadStatic]
		private static Action<Task> childWorkAdder;

		internal readonly Task parent;
        private static int id = -1;
        private CountdownEvent childTasks;
        private TaskCreationOptions taskCreationOptions;

		internal TaskScheduler scheduler;

		private TaskExceptionSlot exSlot;

		private TaskStatus status;

		private TaskActionInvoker invoker;
        internal AtomicBooleanValue executing;

		private TaskCompletionQueue<IContinuation> continuations;

		private CancellationToken token;

		private CancellationTokenRegistration? cancellationRegistration;

        public static TaskFactory Factory { get; } = new TaskFactory();

        public static int? CurrentId => current?.Id;

		public AggregateException Exception
		{
			get
			{
				if (exSlot == null)
				{
					return null;
				}
				exSlot.Observed = true;
				return exSlot.Exception;
			}
		}

		public bool IsCanceled => status == TaskStatus.Canceled;

		public bool IsCompleted => status >= TaskStatus.RanToCompletion;

		public bool IsFaulted => status == TaskStatus.Faulted;

		public TaskCreationOptions CreationOptions => taskCreationOptions & (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler);

		public TaskStatus Status
		{
			get
			{
				return status;
			}
			internal set
			{
				status = value;
				Thread.MemoryBarrier();
			}
		}

		private TaskExceptionSlot ExceptionSlot
		{
			get
			{
				if (exSlot != null)
				{
					return exSlot;
				}
				Interlocked.CompareExchange(ref exSlot, new TaskExceptionSlot(this), null);
				return exSlot;
			}
		}

        public object AsyncState { get; private set; }

        bool IAsyncResult.CompletedSynchronously => true;

		WaitHandle IAsyncResult.AsyncWaitHandle => null;

        public int Id { get; }

        private bool IsContinuation => ContinuationAncestor != null;

        internal Task ContinuationAncestor { get; }

        internal string DisplayActionMethod
		{
			get
			{
				var d = invoker.Action;
				if ((object)d != null)
				{
					return d.Method.ToString();
				}
				return "<none>";
			}
		}

		internal Task Parent => parent;

		public Task(Action action)
			: this(action, TaskCreationOptions.None)
		{
		}

		public Task(Action action, TaskCreationOptions creationOptions)
			: this(action, CancellationToken.None, creationOptions)
		{
		}

		public Task(Action action, CancellationToken cancellationToken)
			: this(action, cancellationToken, TaskCreationOptions.None)
		{
		}

		public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
			: this(TaskActionInvoker.Create(action), null, cancellationToken, creationOptions, current)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			if (creationOptions > (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler) || creationOptions < TaskCreationOptions.None)
			{
				throw new ArgumentOutOfRangeException("creationOptions");
			}
		}

		public Task(Action<object> action, object state)
			: this(action, state, TaskCreationOptions.None)
		{
		}

		public Task(Action<object> action, object state, TaskCreationOptions creationOptions)
			: this(action, state, CancellationToken.None, creationOptions)
		{
		}

		public Task(Action<object> action, object state, CancellationToken cancellationToken)
			: this(action, state, cancellationToken, TaskCreationOptions.None)
		{
		}

		public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
			: this(TaskActionInvoker.Create(action), state, cancellationToken, creationOptions, current)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			if (creationOptions > (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler) || creationOptions < TaskCreationOptions.None)
			{
				throw new ArgumentOutOfRangeException("creationOptions");
			}
		}

		internal Task(TaskActionInvoker invoker, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent, Task contAncestor = null)
		{
			this.invoker = invoker;
			taskCreationOptions = creationOptions;
			this.AsyncState = state;
			Id = Interlocked.Increment(ref id);
			status = (cancellationToken.IsCancellationRequested ? TaskStatus.Canceled : TaskStatus.Created);
			token = cancellationToken;
			this.parent = parent;
			this.ContinuationAncestor = contAncestor;
			if (CheckTaskOptions(taskCreationOptions, TaskCreationOptions.AttachedToParent))
			{
				parent?.AddChild();
			}
			if (token.CanBeCanceled)
			{
				cancellationRegistration = token.Register(delegate(object l)
				{
					((Task)l).CancelReal();
				}, this);
			}
		}

		private static bool CheckTaskOptions(TaskCreationOptions opt, TaskCreationOptions member)
		{
			return (opt & member) == member;
		}

		public void Start()
		{
			Start(TaskScheduler.Current);
		}

		public void Start(TaskScheduler scheduler)
		{
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			if (status >= TaskStatus.WaitingToRun)
			{
				throw new InvalidOperationException("The Task is not in a valid state to be started.");
			}
			if (IsContinuation)
			{
				throw new InvalidOperationException("Start may not be called on a continuation task");
			}
			SetupScheduler(scheduler);
			Schedule();
		}

		internal void SetupScheduler(TaskScheduler scheduler)
		{
			this.scheduler = scheduler;
			Status = TaskStatus.WaitingForActivation;
		}

		public void RunSynchronously()
		{
			RunSynchronously(TaskScheduler.Current);
		}

		public void RunSynchronously(TaskScheduler scheduler)
		{
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			if (Status > TaskStatus.WaitingForActivation)
			{
				throw new InvalidOperationException("The task is not in a valid state to be started");
			}
			SetupScheduler(scheduler);
			var saveStatus = status;
			Status = TaskStatus.WaitingToRun;
			try
			{
				if (scheduler.RunInline(this))
				{
					return;
				}
			}
			catch (Exception inner)
			{
				throw new TaskSchedulerException(inner);
			}
			Status = saveStatus;
			Start(scheduler);
			Wait();
		}

		public Task ContinueWith(Action<Task> continuationAction)
		{
			return ContinueWith(continuationAction, TaskContinuationOptions.None);
		}

		public Task ContinueWith(Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task> continuationAction, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task> continuationAction, TaskScheduler scheduler)
		{
			return ContinueWith(continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task ContinueWith(Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationAction == null)
			{
				throw new ArgumentNullException("continuationAction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			return ContinueWith(TaskActionInvoker.Create(continuationAction), cancellationToken, continuationOptions, scheduler);
		}

		internal Task ContinueWith(TaskActionInvoker invoker, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			var continuation = new Task(invoker, null, cancellationToken, GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(continuation, continuationOptions, scheduler);
			return continuation;
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction)
		{
			return ContinueWith(continuationFunction, TaskContinuationOptions.None);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, TaskScheduler scheduler)
		{
			return ContinueWith(continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationFunction == null)
			{
				throw new ArgumentNullException("continuationFunction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			return ContinueWith<TResult>(TaskActionInvoker.Create(continuationFunction), cancellationToken, continuationOptions, scheduler);
		}

		internal Task<TResult> ContinueWith<TResult>(TaskActionInvoker invoker, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			var continuation = new Task<TResult>(invoker, null, cancellationToken, GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(continuation, continuationOptions, scheduler);
			return continuation;
		}

		internal void ContinueWithCore(Task continuation, TaskContinuationOptions options, TaskScheduler scheduler)
		{
			if ((options & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) == (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion) || (options & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) == (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion) || (options & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) == (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion))
			{
				throw new ArgumentException("continuationOptions", "Some options are mutually exclusive");
			}
			continuation.scheduler = scheduler;
			continuation.Status = TaskStatus.WaitingForActivation;
			ContinueWith(new TaskContinuation(continuation, options));
		}

		internal void ContinueWith(IContinuation continuation)
		{
			if (IsCompleted)
			{
				continuation.Execute();
				return;
			}
			continuations.Add(continuation);
			if (IsCompleted && continuations.Remove(continuation))
			{
				continuation.Execute();
			}
		}

		private void RemoveContinuation(IContinuation continuation)
		{
			continuations.Remove(continuation);
		}

		internal static TaskCreationOptions GetCreationOptions(TaskContinuationOptions kind)
		{
			var options = TaskCreationOptions.None;
			if ((kind & TaskContinuationOptions.AttachedToParent) > TaskContinuationOptions.None)
			{
				options |= TaskCreationOptions.AttachedToParent;
			}
			if ((kind & TaskContinuationOptions.PreferFairness) > TaskContinuationOptions.None)
			{
				options |= TaskCreationOptions.PreferFairness;
			}
			if ((kind & TaskContinuationOptions.LongRunning) > TaskContinuationOptions.None)
			{
				options |= TaskCreationOptions.LongRunning;
			}
			return options;
		}

		internal void Schedule()
		{
			Status = TaskStatus.WaitingToRun;
			if (scheduler != TaskScheduler.Current || childWorkAdder == null || CheckTaskOptions(taskCreationOptions, TaskCreationOptions.PreferFairness))
			{
				scheduler.QueueTask(this);
			}
			else
			{
				childWorkAdder(this);
			}
		}

		private void ThreadStart()
		{
			if (!executing.TryRelaxedSet())
			{
				return;
			}
			if (cancellationRegistration.HasValue)
			{
				cancellationRegistration.Value.Dispose();
				cancellationRegistration = null;
			}
			current = this;
			TaskScheduler.Current = scheduler;
			if (!token.IsCancellationRequested)
			{
				status = TaskStatus.Running;
				try
				{
					InnerInvoke();
				}
				catch (OperationCanceledException oce)
				{
					if (token != CancellationToken.None /*&& oce.CancellationToken == token*/)
					{
						CancelReal();
					}
					else
					{
						HandleGenericException(oce);
					}
				}
				catch (Exception e)
				{
					HandleGenericException(e);
				}
			}
			else
			{
				CancelReal();
			}
			Finish();
		}

		internal bool TrySetCanceled()
		{
			if (IsCompleted)
			{
				return false;
			}
			if (!executing.TryRelaxedSet())
			{
				var sw = default(SpinWait);
				while (!IsCompleted)
				{
					sw.SpinOnce();
				}
				return false;
			}
			CancelReal();
			return true;
		}

		internal bool TrySetException(AggregateException aggregate)
		{
			if (IsCompleted)
			{
				return false;
			}
			if (!executing.TryRelaxedSet())
			{
				var sw = default(SpinWait);
				while (!IsCompleted)
				{
					sw.SpinOnce();
				}
				return false;
			}
			HandleGenericException(aggregate);
			return true;
		}

		internal void Execute(Action<Task> childAdder)
		{
			childWorkAdder = childAdder;
			Execute();
		}

		internal void Execute()
		{
			ThreadStart();
		}

		internal void AddChild()
		{
			if (childTasks == null)
			{
				Interlocked.CompareExchange(ref childTasks, new CountdownEvent(1), null);
			}
			childTasks.AddCount();
		}

		internal void ChildCompleted(AggregateException childEx)
		{
			if (childEx != null)
			{
				if (ExceptionSlot.ChildExceptions == null)
				{
					Interlocked.CompareExchange(ref ExceptionSlot.ChildExceptions, new ConcurrentQueue<AggregateException>(), null);
				}
				ExceptionSlot.ChildExceptions.Enqueue(childEx);
			}
			if (childTasks.Signal() && status == TaskStatus.WaitingForChildrenToComplete)
			{
				Status = TaskStatus.RanToCompletion;
				ProcessChildExceptions();
				ProcessCompleteDelegates();
				if (CheckTaskOptions(taskCreationOptions, TaskCreationOptions.AttachedToParent) && parent != null)
				{
					parent.ChildCompleted(Exception);
				}
			}
		}

		private void InnerInvoke()
		{
			if (IsContinuation)
			{
				invoker.Invoke(ContinuationAncestor, AsyncState, this);
			}
			else
			{
				invoker.Invoke(this, AsyncState, this);
			}
		}

		internal void Finish()
		{
			if (childTasks != null)
			{
				childTasks.Signal();
			}
			if (status == TaskStatus.Running)
			{
				if (childTasks == null || childTasks.IsSet)
				{
					Status = TaskStatus.RanToCompletion;
				}
				else
				{
					Status = TaskStatus.WaitingForChildrenToComplete;
				}
			}
			if (status == TaskStatus.RanToCompletion)
			{
				ProcessCompleteDelegates();
			}
			current = null;
			TaskScheduler.Current = null;
			if (cancellationRegistration.HasValue)
			{
				cancellationRegistration.Value.Dispose();
			}
			if (CheckTaskOptions(taskCreationOptions, TaskCreationOptions.AttachedToParent) && parent != null && status != TaskStatus.WaitingForChildrenToComplete)
			{
				parent.ChildCompleted(Exception);
			}
		}

		private void ProcessCompleteDelegates()
		{
			if (continuations.HasElements)
			{
				IContinuation continuation;
				while (continuations.TryGetNextCompletion(out continuation))
				{
					continuation.Execute();
				}
			}
		}

		private void ProcessChildExceptions()
		{
			if (exSlot != null && exSlot.ChildExceptions != null)
			{
				if (ExceptionSlot.Exception == null)
				{
					exSlot.Exception = new AggregateException();
				}
				AggregateException childEx;
				while (exSlot.ChildExceptions.TryDequeue(out childEx))
				{
					exSlot.Exception.AddChildException(childEx);
				}
			}
		}

		internal void CancelReal()
		{
			Status = TaskStatus.Canceled;
			ProcessCompleteDelegates();
		}

		private void HandleGenericException(Exception e)
		{
			HandleGenericException(new AggregateException(e));
		}

		private void HandleGenericException(AggregateException e)
		{
			ExceptionSlot.Exception = e;
			Thread.MemoryBarrier();
			Status = TaskStatus.Faulted;
			ProcessCompleteDelegates();
		}

		internal void WaitOnChildren()
		{
			if (Status == TaskStatus.WaitingForChildrenToComplete && childTasks != null)
			{
				childTasks.Wait();
			}
		}

		public void Wait()
		{
			Wait(-1, CancellationToken.None);
		}

		public void Wait(CancellationToken cancellationToken)
		{
			Wait(-1, cancellationToken);
		}

		public bool Wait(TimeSpan timeout)
		{
			return Wait(CheckTimeout(timeout), CancellationToken.None);
		}

		public bool Wait(int millisecondsTimeout)
		{
			return Wait(millisecondsTimeout, CancellationToken.None);
		}

		public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
		{
			if (millisecondsTimeout < -1)
			{
				throw new ArgumentOutOfRangeException("millisecondsTimeout");
			}
			var result = true;
			if (!IsCompleted)
			{
				if (Status == TaskStatus.WaitingToRun && millisecondsTimeout == -1 && scheduler != null)
				{
					Execute();
				}
				if (!IsCompleted)
				{
					var evt = new ManualResetEventSlim();
					var slot = new ManualEventSlot(evt);
					try
					{
						ContinueWith(slot);
						result = evt.Wait(millisecondsTimeout, cancellationToken);
					}
					finally
					{
						if (!result)
						{
							RemoveContinuation(slot);
						}
						evt.Dispose();
					}
				}
			}
			if (IsCanceled)
			{
				throw new AggregateException(new TaskCanceledException(this));
			}
			var exception = Exception;
			if (exception != null)
			{
				throw exception;
			}
			if (childTasks != null)
			{
				childTasks.Wait();
			}
			return result;
		}

		public static void WaitAll(params Task[] tasks)
		{
			WaitAll(tasks, -1, CancellationToken.None);
		}

		public static void WaitAll(Task[] tasks, CancellationToken cancellationToken)
		{
			WaitAll(tasks, -1, cancellationToken);
		}

		public static bool WaitAll(Task[] tasks, TimeSpan timeout)
		{
			return WaitAll(tasks, CheckTimeout(timeout), CancellationToken.None);
		}

		public static bool WaitAll(Task[] tasks, int millisecondsTimeout)
		{
			return WaitAll(tasks, millisecondsTimeout, CancellationToken.None);
		}

		public static bool WaitAll(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken)
		{
			if (tasks == null)
			{
				throw new ArgumentNullException("tasks");
			}
			var result = true;
			foreach (var t in tasks)
			{
				if (t == null)
				{
					throw new ArgumentNullException("tasks", "the tasks argument contains a null element");
				}
				result &= t.Status == TaskStatus.RanToCompletion;
			}
			if (!result)
			{
				var evt = new CountdownEvent(tasks.Length);
				var slot = new CountdownEventSlot(evt);
				try
				{
					foreach (var t3 in tasks)
					{
						t3.ContinueWith(slot);
					}
					result = evt.Wait(millisecondsTimeout, cancellationToken);
				}
				finally
				{
					List<Exception> exceptions = null;
					foreach (var t2 in tasks)
					{
						if (result)
						{
							if (t2.Status != TaskStatus.RanToCompletion)
							{
								if (exceptions == null)
								{
									exceptions = new List<Exception>();
								}
								if (t2.Exception != null)
								{
									exceptions.AddRange(t2.Exception.InnerExceptions);
								}
								else
								{
									exceptions.Add(new TaskCanceledException(t2));
								}
							}
						}
						else
						{
							t2.RemoveContinuation(slot);
						}
					}
					evt.Dispose();
					if (exceptions != null)
					{
						throw new AggregateException(exceptions);
					}
				}
			}
			return result;
		}

		public static int WaitAny(params Task[] tasks)
		{
			return WaitAny(tasks, -1, CancellationToken.None);
		}

		public static int WaitAny(Task[] tasks, TimeSpan timeout)
		{
			return WaitAny(tasks, CheckTimeout(timeout));
		}

		public static int WaitAny(Task[] tasks, int millisecondsTimeout)
		{
			return WaitAny(tasks, millisecondsTimeout, CancellationToken.None);
		}

		public static int WaitAny(Task[] tasks, CancellationToken cancellationToken)
		{
			return WaitAny(tasks, -1, cancellationToken);
		}

		public static int WaitAny(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken)
		{
			if (tasks == null)
			{
				throw new ArgumentNullException("tasks");
			}
			if (millisecondsTimeout < -1)
			{
				throw new ArgumentOutOfRangeException("millisecondsTimeout");
			}
			CheckForNullTasks(tasks);
			if (tasks.Length > 0)
			{
				var evt = new ManualResetEventSlim();
				var slot = new ManualEventSlot(evt);
				var result = false;
				try
				{
					for (var j = 0; j < tasks.Length; j++)
					{
						var t3 = tasks[j];
						if (t3.IsCompleted)
						{
							return j;
						}
						t3.ContinueWith(slot);
					}
					if (!(result = evt.Wait(millisecondsTimeout, cancellationToken)))
					{
						return -1;
					}
				}
				finally
				{
					if (!result)
					{
						foreach (var t2 in tasks)
						{
							t2.RemoveContinuation(slot);
						}
					}
					evt.Dispose();
				}
			}
			var firstFinished = -1;
			for (var i = 0; i < tasks.Length; i++)
			{
				var t = tasks[i];
				if (t.IsCompleted)
				{
					firstFinished = i;
					break;
				}
			}
			return firstFinished;
		}

		private static int CheckTimeout(TimeSpan timeout)
		{
			try
			{
				return checked((int)timeout.TotalMilliseconds);
			}
			catch (OverflowException)
			{
				throw new ArgumentOutOfRangeException("timeout");
			}
		}

		private static void CheckForNullTasks(Task[] tasks)
		{
			foreach (var t in tasks)
			{
				if (t == null)
				{
					throw new ArgumentNullException("tasks", "the tasks argument contains a null element");
				}
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!IsCompleted)
			{
				throw new InvalidOperationException("A task may only be disposed if it is in a completion state");
			}
			if (disposing)
			{
				invoker = null;
				AsyncState = null;
				if (cancellationRegistration.HasValue)
				{
					cancellationRegistration.Value.Dispose();
				}
			}
		}

		public Task ContinueWith(Action<Task, object> continuationAction, object state)
		{
			return ContinueWith(continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskScheduler scheduler)
		{
			return ContinueWith(continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationAction == null)
			{
				throw new ArgumentNullException("continuationAction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			var continuation = new Task(TaskActionInvoker.Create(continuationAction), state, cancellationToken, GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(continuation, continuationOptions, scheduler);
			return continuation;
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state)
		{
			return ContinueWith(continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskScheduler scheduler)
		{
			return ContinueWith(continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationFunction == null)
			{
				throw new ArgumentNullException("continuationFunction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			var t = new Task<TResult>(TaskActionInvoker.Create(continuationFunction), state, cancellationToken, GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(t, continuationOptions, scheduler);
			return t;
		}

		public static Task<TResult> FromResult<TResult>(TResult result)
		{
			var tcs = new TaskCompletionSource<TResult>();
			tcs.SetResult(result);
			return tcs.Task;
		}

		public static Task Run(Action action)
		{
			return Run(action, CancellationToken.None);
		}

		public static Task Run(Action action, CancellationToken cancellationToken)
		{
			if (cancellationToken.IsCancellationRequested)
			{
				return TaskConstants.Canceled;
			}
			var t = new Task(action, cancellationToken, TaskCreationOptions.DenyChildAttach);
			t.Start();
			return t;
		}

		public static Task Run(Func<Task> function)
		{
			return Run(function, CancellationToken.None);
		}

		public static Task Run(Func<Task> function, CancellationToken cancellationToken)
		{
			if (cancellationToken.IsCancellationRequested)
			{
				return TaskConstants.Canceled;
			}
			var t = new Task<Task>(function, cancellationToken);
			t.Start();
			return t;
		}

		public static Task<TResult> Run<TResult>(Func<TResult> function)
		{
			return Run(function, CancellationToken.None);
		}

		public static Task<TResult> Run<TResult>(Func<TResult> function, CancellationToken cancellationToken)
		{
			if (cancellationToken.IsCancellationRequested)
			{
				return TaskConstants<TResult>.Canceled;
			}
			var t = new Task<TResult>(function, cancellationToken, TaskCreationOptions.DenyChildAttach);
			t.Start();
			return t;
		}
	}
	[DebuggerTypeProxy(typeof(TaskDebuggerView))]
	[DebuggerDisplay("Id = {Id}, Status = {Status}, Result = {ResultAsString}")]
	public class Task<TResult> : Task
	{
        private TResult value;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public TResult Result
		{
			get
			{
				if (!base.IsCompleted)
				{
					Wait();
				}
				if (base.IsCanceled)
				{
					throw new AggregateException(new TaskCanceledException(this));
				}
				if (base.Exception != null)
				{
					throw base.Exception;
				}
				return value;
			}
			internal set
			{
				this.value = value;
			}
		}

		private string ResultAsString
		{
			get
			{
				if ((base.Status & TaskStatus.RanToCompletion) != 0)
				{
					return string.Concat(value);
				}
				return "<value not available>";
			}
		}

        public new static TaskFactory<TResult> Factory { get; } = new TaskFactory<TResult>();

        public Task(Func<TResult> function)
			: this(function, TaskCreationOptions.None)
		{
		}

		public Task(Func<TResult> function, CancellationToken cancellationToken)
			: this(function, cancellationToken, TaskCreationOptions.None)
		{
		}

		public Task(Func<TResult> function, TaskCreationOptions creationOptions)
			: this(function, CancellationToken.None, creationOptions)
		{
		}

		public Task(Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
			: base(TaskActionInvoker.Create(function), null, cancellationToken, creationOptions, null)
		{
			if (function == null)
			{
				throw new ArgumentNullException("function");
			}
		}

		public Task(Func<object, TResult> function, object state)
			: this(function, state, TaskCreationOptions.None)
		{
		}

		public Task(Func<object, TResult> function, object state, CancellationToken cancellationToken)
			: this(function, state, cancellationToken, TaskCreationOptions.None)
		{
		}

		public Task(Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
			: this(function, state, CancellationToken.None, creationOptions)
		{
		}

		public Task(Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
			: base(TaskActionInvoker.Create(function), state, cancellationToken, creationOptions, null)
		{
			if (function == null)
			{
				throw new ArgumentNullException("function");
			}
		}

		internal Task(TaskActionInvoker invoker, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent, Task contAncestor = null)
			: base(invoker, state, cancellationToken, creationOptions, parent, contAncestor)
		{
		}

		public Task ContinueWith(Action<Task<TResult>> continuationAction)
		{
			return ContinueWith(continuationAction, TaskContinuationOptions.None);
		}

		public Task ContinueWith(Action<Task<TResult>> continuationAction, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task<TResult>> continuationAction, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task<TResult>> continuationAction, TaskScheduler scheduler)
		{
			return ContinueWith(continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task ContinueWith(Action<Task<TResult>> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationAction == null)
			{
				throw new ArgumentNullException("continuationAction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			var t = new Task(TaskActionInvoker.Create(continuationAction), null, cancellationToken, Task.GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(t, continuationOptions, scheduler);
			return t;
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction)
		{
			return ContinueWith(continuationFunction, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, TaskScheduler scheduler)
		{
			return ContinueWith(continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, TNewResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationFunction == null)
			{
				throw new ArgumentNullException("continuationFunction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			var t = new Task<TNewResult>(TaskActionInvoker.Create(continuationFunction), null, cancellationToken, Task.GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(t, continuationOptions, scheduler);
			return t;
		}

		internal bool TrySetResult(TResult result)
		{
			if (base.IsCompleted)
			{
				return false;
			}
			if (!executing.TryRelaxedSet())
			{
				var sw = default(SpinWait);
				while (!base.IsCompleted)
				{
					sw.SpinOnce();
				}
				return false;
			}
			base.Status = TaskStatus.Running;
			value = result;
			Thread.MemoryBarrier();
			Finish();
			return true;
		}

		public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state)
		{
			return ContinueWith(continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler)
		{
			return ContinueWith(continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationAction == null)
			{
				throw new ArgumentNullException("continuationAction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			var t = new Task(TaskActionInvoker.Create(continuationAction), state, cancellationToken, Task.GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(t, continuationOptions, scheduler);
			return t;
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state)
		{
			return ContinueWith(continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken)
		{
			return ContinueWith(continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskContinuationOptions continuationOptions)
		{
			return ContinueWith(continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, TaskScheduler scheduler)
		{
			return ContinueWith(continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler);
		}

		public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
		{
			if (continuationFunction == null)
			{
				throw new ArgumentNullException("continuationFunction");
			}
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			var t = new Task<TNewResult>(TaskActionInvoker.Create(continuationFunction), state, cancellationToken, Task.GetCreationOptions(continuationOptions), parent, this);
			ContinueWithCore(t, continuationOptions, scheduler);
			return t;
		}
	}
}