<PackageReference Include="NUnit" Version="3.7.0" />

AsyncInvocationRegion

using NUnit.Compatibility; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace NUnit.Framework.Internal { internal abstract class AsyncInvocationRegion : IDisposable { private class AsyncTaskInvocationRegion : AsyncInvocationRegion { private const string TaskWaitMethod = "Wait"; private const string TaskResultProperty = "Result"; private const string VoidTaskResultType = "VoidTaskResult"; private const string SystemAggregateException = "System.AggregateException"; private const string InnerExceptionsProperty = "InnerExceptions"; private const BindingFlags TaskResultPropertyBindingFlags = BindingFlags.Instance | BindingFlags.Public; public override object WaitForPendingOperationsToComplete(object invocationResult) { try { TypeExtensions.GetMethod(invocationResult.GetType(), "Wait", new Type[0]).Invoke(invocationResult, null); } catch (TargetInvocationException ex) { ExceptionHelper.Rethrow(GetAllExceptions(ex.InnerException)[0]); } Type[] genericArguments = TypeExtensions.GetGenericArguments(invocationResult.GetType()); if (genericArguments != null && genericArguments.Length == 1 && genericArguments[0].get_Name() == "VoidTaskResult") return null; PropertyInfo property = TypeExtensions.GetProperty(invocationResult.GetType(), "Result", BindingFlags.Instance | BindingFlags.Public); if ((object)property == null) return invocationResult; return property.GetValue(invocationResult, null); } private static IList<Exception> GetAllExceptions(Exception exception) { if ("System.AggregateException".Equals(((object)exception).GetType().FullName)) return (IList<Exception>)TypeExtensions.GetProperty(((object)exception).GetType(), "InnerExceptions").GetValue(exception, null); return new Exception[1] { exception }; } } private const string TaskTypeName = "System.Threading.Tasks.Task"; private const string AsyncAttributeTypeName = "System.Runtime.CompilerServices.AsyncStateMachineAttribute"; private AsyncInvocationRegion() { } public static AsyncInvocationRegion Create(Delegate delegate) { return Create(delegate.GetMethodInfo()); } public static AsyncInvocationRegion Create(MethodInfo method) { if (!IsAsyncOperation(method)) throw new ArgumentException("Either asynchronous support is not available or an attempt \r\nat wrapping a non-async method invocation in an async region was done"); if ((object)method.ReturnType == typeof(void)) throw new ArgumentException("'async void' methods are not supported, please use 'async Task' instead"); return new AsyncTaskInvocationRegion(); } public static bool IsAsyncOperation(MethodInfo method) { string fullName = method.ReturnType.FullName; if (fullName == null) return false; if (!fullName.StartsWith("System.Threading.Tasks.Task")) return CustomAttributeExtensions.GetCustomAttributes(method, false).Any((Attribute attr) => "System.Runtime.CompilerServices.AsyncStateMachineAttribute" == attr.GetType().FullName); return true; } public static bool IsAsyncOperation(Delegate delegate) { return IsAsyncOperation(delegate.GetMethodInfo()); } public abstract object WaitForPendingOperationsToComplete(object invocationResult); public virtual void Dispose() { } } }