示例#1
0
        public Task Execute <TParameters>(IProxy proxy, MethodInfo methodInfo, ref TParameters parameters)
            where TParameters : IValueContainer
        {
            var serviceProxyContext = (ServiceProxyContext)proxy.Context;

            var intent = new ExecuteRoutineIntent
            {
                Id         = _numericIdGenerator.NewId(),
                ServiceId  = serviceProxyContext.Descriptor.Id,
                MethodId   = _routineMethodIdProvider.GetId(methodInfo),
                Parameters = parameters
            };

            var taskResultType =
                // Dispose() does not return a task, and is the only exception.
#warning check if it's really IDisposable.Dispose
                methodInfo.ReturnType == typeof(void)
                ? TaskAccessor.VoidTaskResultType
                : TaskAccessor.GetTaskResultType(methodInfo.ReturnType);

            var taskState = new RoutineReference
            {
                IntentId = intent.Id
#warning must have id of actual routine for dynamic subscription (subscribe after a routine already scheduled).
            };

            var proxyTask = TaskAccessor.CreateTask(taskState, taskResultType);

            bool executeInline = !_transitionScope.IsActive || !IsCalledByRoutine(
                _transitionScope.CurrentMonitor.Context,
                // Skip 2 stack frames: current method and dynamically-generated proxy.
                // WARNING! DO NOT PUT 'new StackFrame()' into a helper method!
                new StackFrame(skipFrames: 2, fNeedFileInfo: false));

            if (executeInline)
            {
                ExecuteAndAwaitInBackground(intent, proxyTask);
            }
            else
            {
                _transitionScope.CurrentMonitor.RegisterIntent(intent, proxyTask);
            }

            return(proxyTask);
        }
示例#2
0
        public Task Execute <TParameters>(IProxy proxy, MethodInfo methodInfo, ref TParameters parameters)
            where TParameters : IValueContainer
        {
            var serviceProxyContext = (ServiceProxyContext)proxy.Context;

            var intent = new ExecuteRoutineIntent
            {
                Id         = _numericIdGenerator.NewId(),
                ServiceId  = serviceProxyContext.Service.Id,
                MethodId   = _routineMethodIdProvider.GetId(methodInfo),
                Parameters = parameters
            };

            var taskResultType =
                // Dispose() does not return a task, and is the only exception.
#warning check if it's really IDisposable.Dispose
                methodInfo.ReturnType == typeof(void)
                ? TaskAccessor.VoidTaskResultType
                : TaskAccessor.GetTaskResultType(methodInfo.ReturnType);

            var taskState = new RoutineReference
            {
                IntentId = intent.Id
#warning must have id of actual routine for dynamic subscription (subscribe after a routine already scheduled).
            };

            var proxyTask = TaskAccessor.CreateTask(taskState, taskResultType);

            if (_transitionScope.IsActive)
            {
                _transitionScope.CurrentMonitor.RegisterIntent(intent, proxyTask);
            }
            else
            {
                ExecuteAndAwaitInBackground(intent, proxyTask);
            }

            return(proxyTask);
        }
示例#3
0
        public void HandleWhenAllAsDetectedContinuation(
            Task whenAllTask, Task[] awaitedTasks,
            ExecuteRoutineIntent awaitedRoutineIntent,
            ITransitionMonitor monitor)
        {
            ExecuteRoutineIntent executeWhenAllIntent;

            lock (whenAllTask)
            {
                var state = whenAllTask.AsyncState as WhenAllProxyTaskState;
                if (state == null)
                {
                    var whenAllIntentId = _numericIdGenerator.NewId();

                    Type itemType   = null;
                    var  resultType = whenAllTask.GetResultType();
                    if (resultType.IsArray)
                    {
                        itemType = resultType.GetElementType();
                    }

                    executeWhenAllIntent = new ExecuteRoutineIntent
                    {
                        Id = whenAllIntentId,

                        ServiceId = new ServiceId
                        {
                            ServiceName = awaitedRoutineIntent.ServiceId.ServiceName,
                            ProxyName   = nameof(IntrinsicRoutines)
                        },

                        MethodId = _routineMethodIdProvider.GetId(
                            IntrinsicRoutines.WhenAllMethodInfo),

                        Parameters = new WhenAllInputParameters
                        {
                            tasks   = awaitedTasks,
                            intents = new ExecuteRoutineIntent[awaitedTasks.Length],
                            // The task result must be an Array, e.g. string[]
                            itemType = itemType
                        }
                    };

                    state = new WhenAllProxyTaskState
                    {
                        IntentId             = whenAllIntentId,
                        ExecuteWhenAllIntent = executeWhenAllIntent
                    };
                    whenAllTask.SetAsyncState(state);

                    monitor.RegisterIntent(executeWhenAllIntent, whenAllTask);
                }
                else
                {
                    executeWhenAllIntent = state.ExecuteWhenAllIntent;
                }
            }

            var index = -1;

            for (var i = 0; i < awaitedTasks.Length; i++)
            {
                if (awaitedTasks[i].AsyncState is ProxyTaskState state &&
                    state.IntentId == awaitedRoutineIntent.Id)
                {
                    index = i;
                    break;
                }
            }
            var parameters = (WhenAllInputParameters)executeWhenAllIntent.Parameters;

            parameters.intents[index] = awaitedRoutineIntent;

            monitor.Context.ScheduledActions.ExecuteRoutineIntents.Remove(awaitedRoutineIntent);

            if (parameters.intents.All(i => i != null))
            {
                whenAllTask.SetAsyncState(new ProxyTaskState
                {
                    IntentId = executeWhenAllIntent.Id
                });
            }
        }