private async Task <InvokeRoutineResult> RunRoutineAsync( ITransitionCarrier transitionCarrier, TransitionDescriptor transitionDescriptor, CancellationToken ct) { var invocationResult = new InvokeRoutineResult(); using (_transitionScope.Enter(transitionDescriptor)) { var transitionMonitor = _transitionScope.CurrentMonitor; var serviceId = await transitionCarrier.GetServiceIdAsync(ct); var methodId = await transitionCarrier.GetRoutineDescriptorAsync(ct); var serviceReference = _serviceResolver.Resolve(serviceId); var methodReference = _methodResolver.Resolve(serviceReference.Definition, methodId); object serviceInstance = serviceReference.GetInstance(); //var serviceStateContainer = _serviceStateValueContainerProvider.CreateContainer(serviceInstance); //var isStatefullService = serviceStateContainer.GetCount() > 0; //if (isStatefullService) // await transitionCarrier.ReadServiceStateAsync(serviceStateContainer, ct); Type taskResultType = methodReference.Definition.MethodInfo.ReturnType == typeof(void) ? TaskAccessor.VoidTaskResultType : TaskAccessor.GetTaskResultType(methodReference.Definition.MethodInfo.ReturnType); Task completionTask; IValueContainer asmValueContainer = null; if (TryCreateAsyncStateMachine(methodReference.Definition.MethodInfo, methodId.IntentId, out var asmInstance, out var asmMetadata)) { var isContinuation = transitionDescriptor.Type == TransitionType.ContinueRoutine; asmValueContainer = await LoadRoutineStateAsync(transitionCarrier, asmInstance, asmMetadata, isContinuation, ct); asmMetadata.Owner.FieldInfo?.SetValue(asmInstance, serviceInstance); transitionMonitor.OnRoutineStart( serviceReference, methodReference, methodId, serviceInstance, asmInstance, (transitionCarrier as TransitionCarrier)?.Caller); try { asmInstance.MoveNext(); completionTask = GetCompletionTask(asmInstance, asmMetadata); } catch (Exception ex) { // The MoveNext() must not throw, but instead complete the task with an error. // try-catch is added just in case for a non-compiler-generated state machine. completionTask = TaskAccessor.FromException(taskResultType, ex); } }
public async Task <InvokeRoutineResult> InvokeAsync( MethodInvocationData data, InvocationPreferences preferences) { var message = new Message { Type = MessageType.InvokeMethod, }; MethodInvocationDataTransformer.Write(message, data, _serializer); var result = new InvokeRoutineResult { Outcome = InvocationOutcome.Scheduled }; if (preferences.Synchronous) { var completionNotification = new TaskCompletionSource <InvokeRoutineResult>(); message.Data["Notification"] = completionNotification; _messageHub.Schedule(message); result = await completionNotification.Task; if (result.Result != null) { result.Result = TaskResult.CreateEmpty(preferences.ResultValueType); _serializer.Populate(_serializer.SerializeToString(result.Result), (IValueContainer)result.Result); } } else if (preferences.LockMessage) { result.MessageHandle = new MessageHandle(message, _messageHub); } else { _messageHub.Schedule(message); } return(result); }