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);
        }
Ejemplo n.º 3
0
 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));
 }