示例#1
0
        public void SetException(Exception exception)
        {
            Task taskIfDebuggingEnabled = this.GetTaskIfDebuggingEnabled();

            if (taskIfDebuggingEnabled != null)
            {
                if (DebuggerSupport.LoggingOn)
                {
                    DebuggerSupport.TraceOperationCompletion(CausalityTraceLevel.Required, taskIfDebuggingEnabled, AsyncStatus.Error);
                }
            }

            AsyncMethodBuilderCore.ThrowAsync(exception, m_synchronizationContext);
            NotifySynchronizationContextOfCompletion();
        }
示例#2
0
        /// <summary>Completes the method builder successfully.</summary>
        public void SetResult()
        {
            Task taskIfDebuggingEnabled = this.GetTaskIfDebuggingEnabled();

            if (taskIfDebuggingEnabled != null)
            {
                if (DebuggerSupport.LoggingOn)
                {
                    DebuggerSupport.TraceOperationCompletion(CausalityTraceLevel.Required, taskIfDebuggingEnabled, AsyncStatus.Completed);
                }
                DebuggerSupport.RemoveFromActiveTasks(taskIfDebuggingEnabled);
            }

            NotifySynchronizationContextOfCompletion();
        }
示例#3
0
            internal void CallMoveNext()
            {
                Task task = m_task;

                if (task != null)
                {
                    DebuggerSupport.TraceSynchronousWorkStart(CausalityTraceLevel.Required, task, CausalitySynchronousWork.Execution);
                }

                ExecutionContext.Run(
                    m_executionContext,
                    state => Unsafe.As <IAsyncStateMachine>(state).MoveNext(),
                    m_stateMachine);

                if (task != null)
                {
                    DebuggerSupport.TraceSynchronousWorkCompletion(CausalityTraceLevel.Required, CausalitySynchronousWork.Execution);
                }
            }
示例#4
0
        public void SetResult()
        {
            var task = m_task;

            if (task == null)
            {
                m_task = s_cachedCompleted;
            }
            else
            {
                if (DebuggerSupport.LoggingOn)
                {
                    DebuggerSupport.TraceOperationCompletion(CausalityTraceLevel.Required, task, AsyncStatus.Completed);
                }
                DebuggerSupport.RemoveFromActiveTasks(task);

                if (!task.TrySetResult(default(VoidTaskResult)))
                {
                    throw new InvalidOperationException(SR.TaskT_TransitionToFinal_AlreadyCompleted);
                }
            }
        }
示例#5
0
 public static void TraceSynchronousWorkCompletion()
 {
     DebuggerSupport.TraceSynchronousWorkCompletion(CausalityTraceLevel.Required, CausalitySynchronousWork.Execution);
 }
示例#6
0
 public static void TraceSynchronousWorkStart(Task task)
 {
     DebuggerSupport.TraceSynchronousWorkStart(CausalityTraceLevel.Required, task, CausalitySynchronousWork.Execution);
 }
示例#7
0
 public static void TraceOperationCompletedError(Task task)
 {
     DebuggerSupport.TraceOperationCompletion(CausalityTraceLevel.Required, task, AsyncStatus.Error);
 }
示例#8
0
 public static void TraceOperationCreation(Task task, string operationName)
 {
     DebuggerSupport.TraceOperationCreation(CausalityTraceLevel.Required, task, operationName, 0);
 }
示例#9
0
 public static void RemoveFromActiveTasks(Task task)
 {
     DebuggerSupport.RemoveFromActiveTasks(task);
 }
示例#10
0
 public static void AddToActiveTasks(Task task)
 {
     DebuggerSupport.AddToActiveTasks(task);
 }
示例#11
0
        private static unsafe Action GetCompletionActionHelper(
            ref Action cachedMoveNextAction,
            ref byte stateMachineAddress,
            EETypePtr stateMachineType,
            Task taskIfDebuggingEnabled)
        {
            // Alert a listening debugger that we can't make forward progress unless it slips threads.
            // If we don't do this, and a method that uses "await foo;" is invoked through funceval,
            // we could end up hooking up a callback to push forward the async method's state machine,
            // the debugger would then abort the funceval after it takes too long, and then continuing
            // execution could result in another callback being hooked up.  At that point we have
            // multiple callbacks registered to push the state machine, which could result in bad behavior.
            //Debugger.NotifyOfCrossThreadDependency();

            MoveNextRunner runner;

            if (cachedMoveNextAction != null)
            {
                Debug.Assert(cachedMoveNextAction.Target is MoveNextRunner);
                runner = (MoveNextRunner)cachedMoveNextAction.Target;
                runner.m_executionContext = ExecutionContext.Capture();
                return(cachedMoveNextAction);
            }

            runner = new MoveNextRunner();
            runner.m_executionContext = ExecutionContext.Capture();
            cachedMoveNextAction      = runner.CallMoveNext;

            if (taskIfDebuggingEnabled != null)
            {
                runner.m_task = taskIfDebuggingEnabled;

                if (DebuggerSupport.LoggingOn)
                {
                    IntPtr eeType = stateMachineType.RawValue;
                    DebuggerSupport.TraceOperationCreation(CausalityTraceLevel.Required, taskIfDebuggingEnabled, "Async: " + eeType.ToString("x"), 0);
                }
                DebuggerSupport.AddToActiveTasks(taskIfDebuggingEnabled);
            }

            //
            // If the state machine is a value type, we need to box it now.
            //
            IAsyncStateMachine boxedStateMachine;

            if (stateMachineType.IsValueType)
            {
                object boxed = RuntimeImports.RhBox(stateMachineType, ref stateMachineAddress);
                Debug.Assert(boxed is IAsyncStateMachine);
                boxedStateMachine = Unsafe.As <IAsyncStateMachine>(boxed);
            }
            else
            {
                boxedStateMachine = Unsafe.As <byte, IAsyncStateMachine>(ref stateMachineAddress);
            }

            runner.m_stateMachine = boxedStateMachine;

#if DEBUG
            //
            // In debug builds, we'll go ahead and call SetStateMachine, even though all of our initialization is done.
            // This way we'll keep forcing state machine implementations to keep the behavior needed by the CLR.
            //
            boxedStateMachine.SetStateMachine(boxedStateMachine);
#endif

            // All done!
            return(cachedMoveNextAction);
        }