合并XAgent
智能大石头 authored at 2023-03-08 20:59:57
2.35 KiB
X_NET20
using System.Collections.Generic;

namespace System.Threading.Tasks
{
	public class TaskCompletionSource<TResult>
	{
        public Task<TResult> Task { get; }

        public TaskCompletionSource()
			: this((object)null, TaskCreationOptions.None)
		{
		}

		public TaskCompletionSource(object state)
			: this(state, TaskCreationOptions.None)
		{
		}

		public TaskCompletionSource(TaskCreationOptions creationOptions)
			: this((object)null, creationOptions)
		{
		}

		public TaskCompletionSource(object state, TaskCreationOptions creationOptions)
		{
			if ((creationOptions & (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning)) != 0)
			{
				throw new ArgumentOutOfRangeException("creationOptions");
			}
			Task = new Task<TResult>(TaskActionInvoker.Empty, state, CancellationToken.None, creationOptions, null);
			Task.SetupScheduler(TaskScheduler.Current);
		}

		public void SetCanceled()
		{
			if (!TrySetCanceled())
			{
				ThrowInvalidException();
			}
		}

		public void SetException(Exception exception)
		{
			if (exception == null)
			{
				throw new ArgumentNullException("exception");
			}
			SetException(new Exception[1] { exception });
		}

		public void SetException(IEnumerable<Exception> exceptions)
		{
			if (!TrySetException(exceptions))
			{
				ThrowInvalidException();
			}
		}

		public void SetResult(TResult result)
		{
			if (!TrySetResult(result))
			{
				ThrowInvalidException();
			}
		}

		private static void ThrowInvalidException()
		{
			throw new InvalidOperationException("The underlying Task is already in one of the three final states: RanToCompletion, Faulted, or Canceled.");
		}

		public bool TrySetCanceled()
		{
			return Task.TrySetCanceled();
		}

		public bool TrySetException(Exception exception)
		{
			if (exception == null)
			{
				throw new ArgumentNullException("exception");
			}
			return TrySetException(new Exception[1] { exception });
		}

		public bool TrySetException(IEnumerable<Exception> exceptions)
		{
			if (exceptions == null)
			{
				throw new ArgumentNullException("exceptions");
			}
			AggregateException aggregate = new AggregateException(exceptions);
			if (aggregate.InnerExceptions.Count == 0)
			{
				throw new ArgumentNullException("exceptions");
			}
			return Task.TrySetException(aggregate);
		}

		public bool TrySetResult(TResult result)
		{
			return Task.TrySetResult(result);
		}
	}
}