#if NET20 || NET30 || NET35 || NET40 || !NET_4_6 using System.Threading.Tasks; namespace System.Runtime.CompilerServices { /// /// Provides a base class used to cache tasks of a specific return type. /// /// Specifies the type of results the cached tasks return. internal class AsyncMethodTaskCache { /// /// A singleton cache for this result type. /// This may be null if there are no cached tasks for this TResult. /// /// internal static readonly AsyncMethodTaskCache Singleton = CreateCache(); static AsyncMethodTaskCache() { } /// /// Creates a non-disposable task. /// /// The result for the task. /// /// The cacheable task. /// internal static TaskCompletionSource CreateCompleted(TResult result) { var completionSource = new TaskCompletionSource(); completionSource.TrySetResult(result); return completionSource; } /// /// Creates a cache. /// /// /// /// A task cache for this result type. /// private static AsyncMethodTaskCache CreateCache() { var type = typeof(TResult); if (type == typeof(bool)) { return (AsyncMethodTaskCache)(object)new AsyncMethodBooleanTaskCache(); } if (type == typeof(int)) { return (AsyncMethodTaskCache)(object)new AsyncMethodInt32TaskCache(); } return null; } /// /// Gets a cached task if one exists. /// /// The result for which we want a cached task. /// /// A cached task if one exists; otherwise, null. /// internal virtual TaskCompletionSource FromResult(TResult result) { return CreateCompleted(result); } } /// /// Provides a cache for Boolean tasks. /// internal sealed class AsyncMethodBooleanTaskCache : AsyncMethodTaskCache { /// /// A true task. /// private readonly TaskCompletionSource _true = CreateCompleted(true); /// /// A false task. /// private readonly TaskCompletionSource _false = CreateCompleted(false); /// /// Gets a cached task for the Boolean result. /// /// true or false /// /// A cached task for the Boolean result. /// internal override TaskCompletionSource FromResult(bool result) { return result ? _true : _false; } } /// /// Provides a cache for zero Int32 tasks. /// internal sealed class AsyncMethodInt32TaskCache : AsyncMethodTaskCache { /// /// The cache of Task{Int32}. /// private static readonly TaskCompletionSource[] _int32Tasks = CreateInt32Tasks(); /// /// The minimum value, inclusive, for which we want a cached task. /// private const int _minInt32ValueInclusive = -1; /// /// The maximum value, exclusive, for which we want a cached task. /// private const int _maxInt32ValueExclusive = 9; /// /// Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX). /// private static TaskCompletionSource[] CreateInt32Tasks() { var completionSourceArray = new TaskCompletionSource[10]; for (var index = 0; index < completionSourceArray.Length; ++index) { completionSourceArray[index] = CreateCompleted(index - 1); } return completionSourceArray; } /// /// Gets a cached task for the zero Int32 result. /// /// The integer value /// /// A cached task for the Int32 result or null if not cached. /// internal override TaskCompletionSource FromResult(int result) { if (result < _minInt32ValueInclusive || result >= _maxInt32ValueExclusive) { return CreateCompleted(result); } return _int32Tasks[result - -1]; } } } #endif