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); }
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); }
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 }); } }