| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- // <copyright>
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- namespace System.Runtime
- {
- using System.Runtime.CompilerServices;
- using System.Threading;
- using System.Threading.Tasks;
- internal static class TaskExtensions
- {
- public static IAsyncResult AsAsyncResult<T>(this Task<T> task, AsyncCallback callback, object state)
- {
- if (task == null)
- {
- throw Fx.Exception.ArgumentNull("task");
- }
- if (task.Status == TaskStatus.Created)
- {
- throw Fx.Exception.AsError(new InvalidOperationException(InternalSR.SFxTaskNotStarted));
- }
- var tcs = new TaskCompletionSource<T>(state);
- task.ContinueWith(
- t =>
- {
- if (t.IsFaulted)
- {
- tcs.TrySetException(t.Exception.InnerExceptions);
- }
- else if (t.IsCanceled)
- {
- // the use of Task.ContinueWith(,TaskContinuationOptions.OnlyOnRanToCompletion)
- // can give us a cancelled Task here with no t.Exception.
- tcs.TrySetCanceled();
- }
- else
- {
- tcs.TrySetResult(t.Result);
- }
- if (callback != null)
- {
- callback(tcs.Task);
- }
- },
- TaskContinuationOptions.ExecuteSynchronously);
- return tcs.Task;
- }
- public static IAsyncResult AsAsyncResult(this Task task, AsyncCallback callback, object state)
- {
- if (task == null)
- {
- throw Fx.Exception.ArgumentNull("task");
- }
- if (task.Status == TaskStatus.Created)
- {
- throw Fx.Exception.AsError(new InvalidOperationException(InternalSR.SFxTaskNotStarted));
- }
- var tcs = new TaskCompletionSource<object>(state);
- task.ContinueWith(
- t =>
- {
- if (t.IsFaulted)
- {
- tcs.TrySetException(t.Exception.InnerExceptions);
- }
- else if (t.IsCanceled)
- {
- // the use of Task.ContinueWith(,TaskContinuationOptions.OnlyOnRanToCompletion)
- // can give us a cancelled Task here with no t.Exception.
- tcs.TrySetCanceled();
- }
- else
- {
- tcs.TrySetResult(null);
- }
- if (callback != null)
- {
- callback(tcs.Task);
- }
- },
- TaskContinuationOptions.ExecuteSynchronously);
- return tcs.Task;
- }
- public static ConfiguredTaskAwaitable SuppressContextFlow(this Task task)
- {
- return task.ConfigureAwait(false);
- }
- public static ConfiguredTaskAwaitable<T> SuppressContextFlow<T>(this Task<T> task)
- {
- return task.ConfigureAwait(false);
- }
- public static ConfiguredTaskAwaitable ContinueOnCapturedContextFlow(this Task task)
- {
- return task.ConfigureAwait(true);
- }
- public static ConfiguredTaskAwaitable<T> ContinueOnCapturedContextFlow<T>(this Task<T> task)
- {
- return task.ConfigureAwait(true);
- }
- public static void Wait<TException>(this Task task)
- {
- try
- {
- task.Wait();
- }
- catch (AggregateException ex)
- {
- throw Fx.Exception.AsError<TException>(ex);
- }
- }
- public static bool Wait<TException>(this Task task, int millisecondsTimeout)
- {
- try
- {
- return task.Wait(millisecondsTimeout);
- }
- catch (AggregateException ex)
- {
- throw Fx.Exception.AsError<TException>(ex);
- }
- }
- public static bool Wait<TException>(this Task task, TimeSpan timeout)
- {
- try
- {
- if (timeout == TimeSpan.MaxValue)
- {
- return task.Wait(Timeout.Infinite);
- }
- else
- {
- return task.Wait(timeout);
- }
- }
- catch (AggregateException ex)
- {
- throw Fx.Exception.AsError<TException>(ex);
- }
- }
- public static void Wait(this Task task, TimeSpan timeout, Action<Exception, TimeSpan, string> exceptionConverter, string operationType)
- {
- bool timedOut = false;
- try
- {
- if (timeout > TimeoutHelper.MaxWait)
- {
- task.Wait();
- }
- else
- {
- timedOut = !task.Wait(timeout);
- }
- }
- catch (Exception ex)
- {
- if (Fx.IsFatal(ex) || exceptionConverter == null)
- {
- throw;
- }
- exceptionConverter(ex, timeout, operationType);
- }
- if (timedOut)
- {
- throw Fx.Exception.AsError(new TimeoutException(InternalSR.TaskTimedOutError(timeout)));
- }
- }
- public static Task<TBase> Upcast<TDerived, TBase>(this Task<TDerived> task) where TDerived : TBase
- {
- return (task.Status == TaskStatus.RanToCompletion) ?
- Task.FromResult((TBase)task.Result) :
- UpcastPrivate<TDerived, TBase>(task);
- }
- private static async Task<TBase> UpcastPrivate<TDerived, TBase>(this Task<TDerived> task) where TDerived : TBase
- {
- return await task.ConfigureAwait(false);
- }
- }
- }
|