#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