Example #1
0
            public override object WaitForPendingOperationsToComplete(object invocationResult)
            {
                var awaitAdapter = AwaitAdapter.FromAwaitable(invocationResult);

                if (!awaitAdapter.IsCompleted)
                {
                    var waitStrategy = MessagePumpStrategy.FromCurrentSynchronizationContext();
                    waitStrategy.WaitForCompletion(awaitAdapter);
                }

                // Future: instead of Wait(), use GetAwaiter() to check awaiter.IsCompleted above
                // and use awaiter.OnCompleted/awaiter.GetResult below.
                // (Implement a ReflectionAwaitAdapter)
                try
                {
                    invocationResult.GetType().GetMethod(TaskWaitMethod, new Type[0]).Invoke(invocationResult, null);
                }
                catch (TargetInvocationException e)
                {
                    IList <Exception> innerExceptions = GetAllExceptions(e.InnerException);
                    ExceptionHelper.Rethrow(innerExceptions[0]);
                }
                var args = invocationResult.GetType().GetGenericArguments();

                if (args != null && args.Length == 1 && args[0].Name == VoidTaskResultType)
                {
                    return(null);
                }

                PropertyInfo taskResultProperty = invocationResult.GetType().GetProperty(TaskResultProperty, TaskResultPropertyBindingFlags);

                return(taskResultProperty != null?taskResultProperty.GetValue(invocationResult, null) : invocationResult);
            }
Example #2
0
        public static AwaitAdapter TryCreate(object awaitable)
        {
            if (awaitable == null)
            {
                return(null);
            }

            var info = GetAsyncInfo(awaitable.GetType());

            if (info == null)
            {
                return(null);
            }

            if (_startImmediateAsTaskMethod == null)
            {
                var asyncHelperMethodsType = info.FSharpAsyncTypeDefinition.GetTypeInfo().Assembly.GetType("Microsoft.FSharp.Control.FSharpAsync");
                if (asyncHelperMethodsType == null)
                {
                    throw new InvalidOperationException("Cannot find non-generic FSharpAsync type in the same assembly as the generic one.");
                }

                _startImmediateAsTaskMethod = asyncHelperMethodsType
                                              .GetMethods(BindingFlags.Public | BindingFlags.Static)
                                              .Single(method =>
                {
                    if (method.Name != "StartImmediateAsTask")
                    {
                        return(false);
                    }
                    var typeArguments = method.GetGenericArguments();
                    if (typeArguments.Length != 1)
                    {
                        return(false);
                    }

                    var parameters = method.GetParameters();
                    if (parameters.Length != 2)
                    {
                        return(false);
                    }

                    if (parameters[0].ParameterType != info.FSharpAsyncTypeDefinition.MakeGenericType(typeArguments[0]))
                    {
                        return(false);
                    }

                    Type someType;
                    return(parameters[1].ParameterType.IsFSharpOption(out someType) &&
                           someType.FullName == "System.Threading.CancellationToken");
                });
            }

            var task = _startImmediateAsTaskMethod
                       .MakeGenericMethod(info.ResultType)
                       .Invoke(null, new[] { awaitable, null });

            return(AwaitAdapter.FromAwaitable(task));
        }
Example #3
0
        public static object Await(Func <object> invoke)
        {
            Guard.ArgumentNotNull(invoke, nameof(invoke));

            using (InitializeExecutionEnvironment())
            {
                var awaitAdapter = AwaitAdapter.FromAwaitable(invoke.Invoke());

                if (!awaitAdapter.IsCompleted)
                {
                    var waitStrategy = MessagePumpStrategy.FromCurrentSynchronizationContext();
                    waitStrategy.WaitForCompletion(awaitAdapter);
                }

                return(awaitAdapter.GetResult());
            }
        }
Example #4
0
        public static object Await(Func <object> invoke)
        {
            Guard.ArgumentNotNull(invoke, nameof(invoke));

            object invocationResult;

            using (InitializeExecutionEnvironment())
            {
                invocationResult = invoke.Invoke();
                if (invocationResult == null || !IsTaskType(invocationResult.GetType()))
                {
                    throw new InvalidOperationException("The delegate did not return a Task."); // General awaitable support coming soon.
                }
                var awaitAdapter = AwaitAdapter.FromAwaitable(invocationResult);

                if (!awaitAdapter.IsCompleted)
                {
                    var waitStrategy = MessagePumpStrategy.FromCurrentSynchronizationContext();
                    waitStrategy.WaitForCompletion(awaitAdapter);
                }
            }

            // Future: instead of Wait(), use GetAwaiter() to check awaiter.IsCompleted above
            // and use awaiter.OnCompleted/awaiter.GetResult below.
            // (Implement a ReflectionAwaitAdapter)
            try
            {
                invocationResult.GetType().GetMethod(TaskWaitMethod, new Type[0]).Invoke(invocationResult, null);
            }
            catch (TargetInvocationException e)
            {
                IList <Exception> innerExceptions = GetAllExceptions(e.InnerException);
                ExceptionHelper.Rethrow(innerExceptions[0]);
            }
            var genericArguments = invocationResult.GetType().GetGenericArguments();

            if (genericArguments.Length == 1 && genericArguments[0].Name == VoidTaskResultType)
            {
                return(null);
            }

            PropertyInfo taskResultProperty = invocationResult.GetType().GetProperty(TaskResultProperty, TaskResultPropertyBindingFlags);

            return(taskResultProperty != null?taskResultProperty.GetValue(invocationResult, null) : invocationResult);
        }