Пример #1
0
        public static ClrInstance?TryResolveContinuationInstance(ClrInstance continuation, CausalityContext context)
        {
            if (continuation.IsOfType(context.Registry.StandardTaskContinuationType))
            {
                return(continuation["m_task"].Instance);
            }

            if (continuation.IsTaskCompletionSource(context))
            {
                return(continuation["m_task"].Instance);
            }

            if (continuation.IsCompletedTaskContinuation(context))
            {
                // Continuation is a special sentinel instance that indicates that the task is completed.
                return(null);
            }

            if (continuation.IsOfType(typeof(Action), context))
            {
                return(TryResolveContinuationForAction(continuation, context));
            }

            if (continuation.IsOfType(context.Registry.AwaitTaskContinuationIndex) || continuation.IsOfType(context.Registry.TaskIndex))
            {
                return(TryResolveContinuationForAction(continuation["m_action"].Instance, context));
            }

            // Need to compare by name since GetTypeByName does not work for the generic type during initialization
            if (continuation.IsListOfObjects())
            {
                Contract.Assert(false, "Please call 'TryResolveContinuations' for a list of continuations.");
            }

            return(null);
        }
Пример #2
0
        public static ClrInstance?TryResolveContinuationForAction(ClrInstance instance, CausalityContext context)
        {
            Contract.Requires(instance.IsOfType(typeof(Action), context), $"A given instance should be of type System.Action, but was '{instance.Type.TypeToString(context.Registry)}'");

            var continuation = instance;
            var actionTarget = continuation["_target"].Instance;

            if (actionTarget.IsOfType(context.Registry.ContinuationWrapperType))
            {
                // Do we need to look at the m_innerTask field as well here?
                return(actionTarget["m_continuation"].Instance);
            }

            // If the action points to a closure, it is possible that the closure
            // is responsible for setting the result of a task completion source.
            // There is no simple way to detect whether this is the case or not, so we will add the "edge" unconditionally.
            if (actionTarget.Type.IsClosure())
            {
                foreach (var field in actionTarget.Fields)
                {
                    if (field.Instance.IsTaskCompletionSource(context))
                    {
                        return(field.Instance);
                    }
                }
            }

            // m_stateMachine field is defined in AsyncMethodBuilderCore and in MoveNextRunner.
            var stateMachine = actionTarget.TryGetFieldValue("m_stateMachine")?.Instance;

            if (stateMachine.IsNull())
            {
                return(null);
            }

            return(stateMachine);
        }