AsyncToSyncAdapter
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
namespace NUnit.Framework.Internal
{
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Runtime.CompilerServices.Nullable(0)]
internal static class AsyncToSyncAdapter
{
private static readonly Type AsyncStateMachineAttributeType = Type.GetType("System.Runtime.CompilerServices.AsyncStateMachineAttribute, System.Runtime", false);
[System.Runtime.CompilerServices.NullableContext(1)]
public static bool IsAsyncOperation(MethodInfo method)
{
if (!AwaitAdapter.IsAwaitable(method.ReturnType)) {
if ((object)AsyncStateMachineAttributeType != null)
return method.IsDefined(AsyncStateMachineAttributeType, false);
return false;
}
return true;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static bool IsAsyncOperation(Delegate delegate)
{
return IsAsyncOperation(delegate.GetMethodInfo());
}
public static object Await(TestExecutionContext context, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Func<object> invoke)
{
return Await<object>(context, invoke);
}
public static TResult Await<TResult>(TestExecutionContext context, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] Func<object> invoke)
{
Guard.ArgumentNotNull(invoke, "invoke");
using (InitializeExecutionEnvironment(context)) {
AwaitAdapter awaitAdapter = AwaitAdapter.FromAwaitable(invoke());
if (!awaitAdapter.IsCompleted) {
MessagePumpStrategy messagePumpStrategy = MessagePumpStrategy.FromCurrentSynchronizationContext();
messagePumpStrategy.WaitForCompletion(awaitAdapter);
}
return (TResult)awaitAdapter.GetResult();
}
}
private static IDisposable InitializeExecutionEnvironment(TestExecutionContext executionContext)
{
if ((executionContext != null && executionContext.IsSingleThreaded) || Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) {
SynchronizationContext context = SynchronizationContext.Current;
if (context == null || context.GetType() == typeof(SynchronizationContext)) {
SingleThreadedTestSynchronizationContext singleThreadedContext = new SingleThreadedTestSynchronizationContext(TimeSpan.FromSeconds(10));
SetSynchronizationContext(singleThreadedContext);
return On.Dispose(delegate {
SetSynchronizationContext(context);
singleThreadedContext.Dispose();
});
}
}
return null;
}
private static void SetSynchronizationContext(SynchronizationContext syncContext)
{
SynchronizationContext.SetSynchronizationContext(syncContext);
}
}
}