public void SetResult(T result) { if (this.currentContext != null) { var _currentContext = this.currentContext; this.currentContext = this.currentContext.prev; _currentContext.awaiter.SetResult(result); } else { this.resultAwaiter.SetResult(result); } }
public void AwaitUnsafeOnCompleted <TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { switch (awaiter) { case IChaosContinuationConsumer <T> consumer: { // save and capture current StateMachine. var clonedStateMachine = CloneStateMachine(stateMachine); var scheduler = new Scheduler(prepare => { var context = new ChaosContinuationContext() { awaiter = new ChaosAwaiter <T>(), continuation = () => { var _clonedStateMachine = clonedStateMachine; clonedStateMachine = CloneStateMachine(_clonedStateMachine); prepare(); _clonedStateMachine.MoveNext(); }, }; lock (this.gate) { this.pendingQueue.Enqueue(context); } return(new ChaosTask <T>(context.awaiter)); }, this.Schedule, this.Abandon); consumer.SetScheduler(scheduler); } break; default: awaiter.OnCompleted(stateMachine.MoveNext); break; } }
private void Schedule(bool hasPriority) { lock (this.gate) { if (this.isRunning) { if (!hasPriority) { return; } if (this.isScheduling) { if (hasPriority) { this.scheduleRequired = true; } return; } } this.isScheduling = true; } var guard = true; this.scheduleRequired = true; this.isRunning = true; while (true) { ChaosContinuationContext context; lock (this.gate) { var _scheduleRequired = this.scheduleRequired; this.scheduleRequired = false; if (!_scheduleRequired || this.pendingQueue.Count == 0) { if (this.pendingQueue.Count == 0) { Abandon(); } this.isScheduling = false; break; } context = this.pendingQueue.Dequeue(); } context.awaiter.OnCompleted(() => { if (guard) { if (this.pendingQueue.Count == 0) { guard = false; this.resultAwaiter.SetResult(context.awaiter.GetResult()); } Schedule(true); } }); context.prev = this.currentContext; this.currentContext = context; context.continuation(); } }