You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
12 KiB
253 lines
12 KiB
5 years ago
|
#if NET20 || NET30 || NET35 || NET40 || !NET_4_6
|
||
|
|
||
|
using System.Security;
|
||
|
using System.Threading.Tasks;
|
||
|
|
||
|
namespace System.Runtime.CompilerServices
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Provides an awaitable object that allows for configured awaits on <see cref="T:System.Threading.Tasks.Task`1"/>.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <remarks>
|
||
|
/// This type is intended for compiler use only.
|
||
|
/// </remarks>
|
||
|
public struct ConfiguredTaskAwaitable<TResult>
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The underlying awaitable on whose logic this awaitable relies.
|
||
|
/// </summary>
|
||
|
private readonly ConfiguredTaskAwaiter _configuredTaskAwaiter;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Initializes the <see cref="T:System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="task">The awaitable <see cref="T:System.Threading.Tasks.Task`1"/>.</param><param name="continueOnCapturedContext">true to attempt to marshal the continuation back to the original context captured; otherwise, false.
|
||
|
/// </param>
|
||
|
internal ConfiguredTaskAwaitable(Task<TResult> task, bool continueOnCapturedContext)
|
||
|
{
|
||
|
_configuredTaskAwaiter = new ConfiguredTaskAwaiter(task, continueOnCapturedContext);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets an awaiter for this awaitable.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <returns>
|
||
|
/// The awaiter.
|
||
|
/// </returns>
|
||
|
public ConfiguredTaskAwaiter GetAwaiter()
|
||
|
{
|
||
|
return _configuredTaskAwaiter;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Provides an awaiter for a <see cref="T:System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1"/>.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <remarks>
|
||
|
/// This type is intended for compiler use only.
|
||
|
/// </remarks>
|
||
|
public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The task being awaited.
|
||
|
/// </summary>
|
||
|
private readonly Task<TResult> _task;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Whether to attempt marshaling back to the original context.
|
||
|
/// </summary>
|
||
|
private readonly bool _continueOnCapturedContext;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets whether the task being awaited is completed.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <remarks>
|
||
|
/// This property is intended for compiler user rather than use directly in code.
|
||
|
/// </remarks>
|
||
|
/// <exception cref="T:System.NullReferenceException">The awaiter was not properly initialized.</exception>
|
||
|
public bool IsCompleted
|
||
|
{
|
||
|
get { return _task.IsCompleted; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Initializes the <see cref="T:System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="task">The awaitable <see cref="T:System.Threading.Tasks.Task`1"/>.</param><param name="continueOnCapturedContext">true to attempt to marshal the continuation back to the original context captured; otherwise, false.
|
||
|
/// </param>
|
||
|
internal ConfiguredTaskAwaiter(Task<TResult> task, bool continueOnCapturedContext)
|
||
|
{
|
||
|
_task = task;
|
||
|
_continueOnCapturedContext = continueOnCapturedContext;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Schedules the continuation onto the <see cref="T:System.Threading.Tasks.Task"/> associated with this <see cref="T:System.Runtime.CompilerServices.TaskAwaiter"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="continuation">The action to invoke when the await operation completes.</param><exception cref="T:System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception><exception cref="T:System.NullReferenceException">The awaiter was not properly initialized.</exception>
|
||
|
/// <remarks>
|
||
|
/// This method is intended for compiler user rather than use directly in code.
|
||
|
/// </remarks>
|
||
|
public void OnCompleted(Action continuation)
|
||
|
{
|
||
|
TaskAwaiter.OnCompletedInternal(_task, continuation, _continueOnCapturedContext);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Schedules the continuation onto the <see cref="T:System.Threading.Tasks.Task"/> associated with this <see cref="T:System.Runtime.CompilerServices.TaskAwaiter"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="continuation">The action to invoke when the await operation completes.</param><exception cref="T:System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception><exception cref="T:System.InvalidOperationException">The awaiter was not properly initialized.</exception>
|
||
|
/// <remarks>
|
||
|
/// This method is intended for compiler user rather than use directly in code.
|
||
|
/// </remarks>
|
||
|
[SecurityCritical]
|
||
|
public void UnsafeOnCompleted(Action continuation)
|
||
|
{
|
||
|
TaskAwaiter.OnCompletedInternal(_task, continuation, true);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Ends the await on the completed <see cref="T:System.Threading.Tasks.Task`1"/>.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <returns>
|
||
|
/// The result of the completed <see cref="T:System.Threading.Tasks.Task`1"/>.
|
||
|
/// </returns>
|
||
|
/// <exception cref="T:System.NullReferenceException">The awaiter was not properly initialized.</exception><exception cref="T:System.InvalidOperationException">The task was not yet completed.</exception><exception cref="T:System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception><exception cref="T:System.Exception">The task completed in a Faulted state.</exception>
|
||
|
public TResult GetResult()
|
||
|
{
|
||
|
TaskAwaiter.ValidateEnd(_task);
|
||
|
return _task.Result;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Provides an awaitable object that allows for configured awaits on <see cref="T:System.Threading.Tasks.Task"/>.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <remarks>
|
||
|
/// This type is intended for compiler use only.
|
||
|
/// </remarks>
|
||
|
public struct ConfiguredTaskAwaitable
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The task being awaited.
|
||
|
/// </summary>
|
||
|
private readonly ConfiguredTaskAwaiter _configuredTaskAwaiter;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Initializes the <see cref="T:System.Runtime.CompilerServices.ConfiguredTaskAwaitable"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="task">The awaitable <see cref="T:System.Threading.Tasks.Task"/>.</param><param name="continueOnCapturedContext">true to attempt to marshal the continuation back to the original context captured; otherwise, false.
|
||
|
/// </param>
|
||
|
internal ConfiguredTaskAwaitable(Task task, bool continueOnCapturedContext)
|
||
|
{
|
||
|
_configuredTaskAwaiter = new ConfiguredTaskAwaiter(task, continueOnCapturedContext);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets an awaiter for this awaitable.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <returns>
|
||
|
/// The awaiter.
|
||
|
/// </returns>
|
||
|
public ConfiguredTaskAwaiter GetAwaiter()
|
||
|
{
|
||
|
return _configuredTaskAwaiter;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Provides an awaiter for a <see cref="T:System.Runtime.CompilerServices.ConfiguredTaskAwaitable"/>.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <remarks>
|
||
|
/// This type is intended for compiler use only.
|
||
|
/// </remarks>
|
||
|
public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The task being awaited.
|
||
|
/// </summary>
|
||
|
private readonly Task _task;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Whether to attempt marshaling back to the original context.
|
||
|
/// </summary>
|
||
|
private readonly bool _continueOnCapturedContext;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets whether the task being awaited is completed.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <remarks>
|
||
|
/// This property is intended for compiler user rather than use directly in code.
|
||
|
/// </remarks>
|
||
|
/// <exception cref="T:System.NullReferenceException">The awaiter was not properly initialized.</exception>
|
||
|
public bool IsCompleted
|
||
|
{
|
||
|
get { return _task.IsCompleted; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Initializes the <see cref="T:System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="task">The <see cref="T:System.Threading.Tasks.Task"/> to await.</param><param name="continueOnCapturedContext">true to attempt to marshal the continuation back to the original context captured
|
||
|
/// when BeginAwait is called; otherwise, false.
|
||
|
/// </param>
|
||
|
internal ConfiguredTaskAwaiter(Task task, bool continueOnCapturedContext)
|
||
|
{
|
||
|
_task = task;
|
||
|
_continueOnCapturedContext = continueOnCapturedContext;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Schedules the continuation onto the <see cref="T:System.Threading.Tasks.Task"/> associated with this <see cref="T:System.Runtime.CompilerServices.TaskAwaiter"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="continuation">The action to invoke when the await operation completes.</param>
|
||
|
/// <exception cref="T:System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
|
||
|
/// <exception cref="T:System.NullReferenceException">The awaiter was not properly initialized.</exception>
|
||
|
/// <remarks>
|
||
|
/// This method is intended for compiler user rather than use directly in code.
|
||
|
/// </remarks>
|
||
|
public void OnCompleted(Action continuation)
|
||
|
{
|
||
|
TaskAwaiter.OnCompletedInternal(_task, continuation, _continueOnCapturedContext);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Schedules the continuation onto the <see cref="T:System.Threading.Tasks.Task"/> associated with this <see cref="T:System.Runtime.CompilerServices.TaskAwaiter"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="continuation">The action to invoke when the await operation completes.</param>
|
||
|
/// <exception cref="T:System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
|
||
|
/// <exception cref="T:System.InvalidOperationException">The awaiter was not properly initialized.</exception>
|
||
|
/// <remarks>
|
||
|
/// This method is intended for compiler user rather than use directly in code.
|
||
|
/// </remarks>
|
||
|
[SecurityCritical]
|
||
|
public void UnsafeOnCompleted(Action continuation)
|
||
|
{
|
||
|
TaskAwaiter.OnCompletedInternal(_task, continuation, true);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Ends the await on the completed <see cref="T:System.Threading.Tasks.Task"/>.
|
||
|
/// </summary>
|
||
|
///
|
||
|
/// <returns>
|
||
|
/// The result of the completed <see cref="T:System.Threading.Tasks.Task`1"/>.
|
||
|
/// </returns>
|
||
|
/// <exception cref="T:System.NullReferenceException">The awaiter was not properly initialized.</exception><exception cref="T:System.InvalidOperationException">The task was not yet completed.</exception><exception cref="T:System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception><exception cref="T:System.Exception">The task completed in a Faulted state.</exception>
|
||
|
public void GetResult()
|
||
|
{
|
||
|
TaskAwaiter.ValidateEnd(_task);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|