合并主线最近几年来的主要更新,重点推进TinyHttpClient,替代HttpClient
大石头 authored at 2023-03-08 18:39:12
1.62 KiB
X_NET20
namespace System.Threading.Tasks
{
	public static class TaskExtensions
	{
		private const TaskContinuationOptions opt = TaskContinuationOptions.ExecuteSynchronously;

		public static Task<TResult> Unwrap<TResult>(this Task<Task<TResult>> task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}
			TaskCompletionSource<TResult> src = new TaskCompletionSource<TResult>();
			task.ContinueWith(delegate(Task<Task<TResult>> t1)
			{
				CopyCat(t1, src, delegate
				{
					t1.Result.ContinueWith(delegate(Task<TResult> t2)
					{
						CopyCat(t2, src, delegate
						{
							src.SetResult(t2.Result);
						});
					}, TaskContinuationOptions.ExecuteSynchronously);
				});
			}, TaskContinuationOptions.ExecuteSynchronously);
			return src.Task;
		}

		public static Task Unwrap(this Task<Task> task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}
			TaskCompletionSource<object> src = new TaskCompletionSource<object>();
			task.ContinueWith(delegate(Task<Task> t1)
			{
				CopyCat(t1, src, delegate
				{
					t1.Result.ContinueWith(delegate(Task t2)
					{
						CopyCat(t2, src, delegate
						{
							src.SetResult(null);
						});
					}, TaskContinuationOptions.ExecuteSynchronously);
				});
			}, TaskContinuationOptions.ExecuteSynchronously);
			return src.Task;
		}

		private static void CopyCat<TResult>(Task source, TaskCompletionSource<TResult> dest, Action normalAction)
		{
			if (source.IsCanceled)
			{
				dest.SetCanceled();
			}
			else if (source.IsFaulted)
			{
				dest.SetException(source.Exception.InnerExceptions);
			}
			else
			{
				normalAction();
			}
		}
	}
}