public static AwaiterInfo TryCreate(TypeInfo type) { Debug.Assert(type != null); if (!NotifyCompletionTypeInfo.IsAssignableFrom(type)) { return(null); } var isCompletedMethod = type .GetRuntimeProperties() .SingleOrDefault(z => z.Name == nameof(TaskAwaiter.IsCompleted) && z.PropertyType == typeof(bool) && z.GetIndexParameters().Length == 0) ?.GetMethod; if (isCompletedMethod == null) { return(null); } var getResultMethod = type .GetRuntimeMethods() .SingleOrDefault(z => z.Name == nameof(TaskAwaiter.GetResult) && z.GetParameters().Length == 0); if (getResultMethod == null) { return(null); } var info = new AwaiterInfo(type) { OnCompletedMethod = type .GetRuntimeInterfaceMap(typeof(INotifyCompletion)).TargetMethods .Single(z => z.Name == nameof(INotifyCompletion.OnCompleted)), IsCompletedMethod = isCompletedMethod, GetResultMethod = getResultMethod }; if (CriticalNotifyCompletionTypeInfo.IsAssignableFrom(type)) { info.UnsafeOnCompletedMethod = type .GetRuntimeInterfaceMap(typeof(ICriticalNotifyCompletion)).TargetMethods .SingleOrDefault(z => z.Name == nameof(ICriticalNotifyCompletion.UnsafeOnCompleted)); } return(info); }
public static AwaitableInfo TryCreate([NotNull] Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var runtimeMethods = type.GetRuntimeMethods().ToArray(); var getAwaiterMethod = runtimeMethods.FirstOrDefault(z => z.Name == nameof(Task.GetAwaiter) && z.ReturnType != typeof(void) && z.GetParameters().Length == 0); if (getAwaiterMethod == null) { return(null); } var awaiterType = getAwaiterMethod.ReturnType; var awaiterInfo = AwaiterInfo.TryCreate(awaiterType.GetTypeInfo()); if (awaiterInfo == null) { return(null); } var info = new AwaitableInfo(type, getAwaiterMethod, awaiterInfo) { ConfigureAwaitMethod = runtimeMethods.FirstOrDefault(z => z.Name == nameof(Task.ConfigureAwait) && z.ReturnType != typeof(void) && z.GetParameters().Length == 1 && z.GetParameters()[0].ParameterType == typeof(bool)) }; return(info); }
public AwaiterAdapterImpl(AwaiterInfo info, FunctionInvokerResolver funcResolver) : base(info, funcResolver) { this._getResultInvoker = funcResolver.Resolve(info.GetResultMethod).AsObjectMethodInvoker <TAwaiter, TResult>(); }
protected AwaiterAdapter([NotNull] AwaiterInfo info) { this.AwaiterInfo = info ?? throw new ArgumentNullException(nameof(info)); }
private AwaitableInfo([NotNull] Type awaitableType, [NotNull] MethodInfo getAwaiterMethod, [NotNull] AwaiterInfo awaiterInfo) { this.AwaitableType = awaitableType ?? throw new ArgumentNullException(nameof(awaitableType)); this.GetAwaiterMethod = getAwaiterMethod ?? throw new ArgumentNullException(nameof(getAwaiterMethod)); this.AwaiterInfo = awaiterInfo ?? throw new ArgumentNullException(nameof(awaiterInfo)); }