#if NET20 || NET30 || NET35 || NET40 || !NET_4_6 using System.Security; using System.Security.Permissions; using System.Threading; using System.Threading.Tasks; namespace System.Runtime.CompilerServices { /// Provides an awaitable context for switching into a target environment. /// This type is intended for compiler use only. public struct YieldAwaitable { /// Gets an awaiter for this . /// An awaiter for this awaitable. /// This method is intended for compiler user rather than use directly in code. public YieldAwaiter GetAwaiter() { return new YieldAwaiter(); } /// Provides an awaiter that switches into a target environment. /// This type is intended for compiler use only. [HostProtection(Synchronization = true, ExternalThreading = true)] public struct YieldAwaiter : ICriticalNotifyCompletion { /// WaitCallback that invokes the Action supplied as object state. private static readonly WaitCallback _waitCallbackRunAction = RunAction; /// Gets whether a yield is not required. /// This property is intended for compiler user rather than use directly in code. public bool IsCompleted { get { return false; } } /// Ends the await operation. public void GetResult() { // Empty } /// Posts the back to the current context. /// The action to invoke asynchronously. /// The argument is null (Nothing in Visual Basic). [SecuritySafeCritical] public void OnCompleted(Action continuation) { if (continuation == null) { throw new ArgumentNullException("continuation"); } if (TaskScheduler.Current == TaskScheduler.Default) { ThreadPool.QueueUserWorkItem(_waitCallbackRunAction, continuation); } else { Task.Factory.StartNew(continuation, default(CancellationToken), TaskCreationOptions.PreferFairness, TaskScheduler.Current); } } /// Posts the back to the current context. /// The action to invoke asynchronously. /// The argument is null (Nothing in Visual Basic). [SecurityCritical] public void UnsafeOnCompleted(Action continuation) { if (continuation == null) { throw new ArgumentNullException("continuation"); } if (TaskScheduler.Current == TaskScheduler.Default) { //ThreadPool.UnsafeQueueUserWorkItem(_waitCallbackRunAction, continuation); ThreadPool.QueueUserWorkItem(_waitCallbackRunAction, continuation); } else { Task.Factory.StartNew(continuation, default(CancellationToken), TaskCreationOptions.PreferFairness, TaskScheduler.Current); } } /// Runs an Action delegate provided as state. /// The Action delegate to invoke. private static void RunAction(object state) { ((Action)state)(); } } } } #endif