AwaitAdapter
Adapts various styles of asynchronous waiting to a common API.
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace NUnit.Framework.Internal
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal abstract class AwaitAdapter
{
public abstract bool IsCompleted { get; }
public abstract void OnCompleted(Action action);
public abstract void BlockUntilCompleted();
[System.Runtime.CompilerServices.NullableContext(2)]
public abstract object GetResult();
public static bool IsAwaitable(Type awaitableType)
{
if (!CSharpPatternBasedAwaitAdapter.IsAwaitable(awaitableType))
return FSharpAsyncAwaitAdapter.IsAwaitable(awaitableType);
return true;
}
public static Type GetResultType(Type awaitableType)
{
object resultType = CSharpPatternBasedAwaitAdapter.GetResultType(awaitableType);
if (resultType == null) {
resultType = FSharpAsyncAwaitAdapter.GetResultType(awaitableType);
if (resultType == null)
throw new InvalidOperationException("Cannot determine result type for: " + awaitableType?.ToString());
}
return (Type)resultType;
}
public static AwaitAdapter FromAwaitable([System.Runtime.CompilerServices.Nullable(2)] object awaitable)
{
if (awaitable == null)
throw new InvalidOperationException("A null reference cannot be awaited.");
Task task = awaitable as Task;
if (task != null)
return TaskAwaitAdapter.Create(task);
if (awaitable is ValueTask) {
ValueTask task2 = (ValueTask)awaitable;
return ValueTaskAwaitAdapter.Create(task2);
}
AwaitAdapter awaitAdapter = ValueTaskAwaitAdapter.TryCreate(awaitable) ?? CSharpPatternBasedAwaitAdapter.TryCreate(awaitable) ?? FSharpAsyncAwaitAdapter.TryCreate(awaitable);
if (awaitAdapter != null)
return awaitAdapter;
throw new NotSupportedException("NUnit can only await objects which follow the C# specification for awaitable expressions.");
}
}
}