网上演练
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.

94 lines
4.0 KiB

#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
{
/// <summary>Provides an awaitable context for switching into a target environment.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
public struct YieldAwaitable
{
/// <summary>Gets an awaiter for this <see cref="YieldAwaitable"/>.</summary>
/// <returns>An awaiter for this awaitable.</returns>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public YieldAwaiter GetAwaiter()
{
return new YieldAwaiter();
}
/// <summary>Provides an awaiter that switches into a target environment.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
[HostProtection(Synchronization = true, ExternalThreading = true)]
public struct YieldAwaiter : ICriticalNotifyCompletion
{
/// <summary>WaitCallback that invokes the Action supplied as object state.</summary>
private static readonly WaitCallback _waitCallbackRunAction = RunAction;
/// <summary>Gets whether a yield is not required.</summary>
/// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
public bool IsCompleted
{
get { return false; }
}
/// <summary>Ends the await operation.</summary>
public void GetResult()
{
// Empty
}
/// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
/// <param name="continuation">The action to invoke asynchronously.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
[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);
}
}
/// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
/// <param name="continuation">The action to invoke asynchronously.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
[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);
}
}
/// <summary>Runs an Action delegate provided as state.</summary>
/// <param name="state">The Action delegate to invoke.</param>
private static void RunAction(object state)
{
((Action)state)();
}
}
}
}
#endif