public void TryHandlePostMoveNext(ITransitionMonitor monitor) { if (!TryFindDelayAwaitedTask(monitor.Context.RoutineStateMachine, out var awaitedTask)) { return; } if (DelayPromiseAccessor.IsDelayPromise(awaitedTask) && DelayPromiseAccessor.TryGetTimerStartAndDelay(awaitedTask, out var timerStart, out var timerDelay) #warning Needs a configuration setting for the minimum delay. If a delay is too short, it might be too expensive to try to save the state of a routine. Also, add ability to opt in/out auto save? //&& timerDelay > TimeSpan.FromSeconds(5) && DelayPromiseAccessor.TryCancelTimer(awaitedTask)) { awaitedTask.ResetContinuation(); awaitedTask.TrySetResult(null); monitor.OnCheckpointIntent(resumeTime: timerStart + timerDelay); }
private bool TryFindDelayPromise( IAsyncStateMachine stateMachine, out Task delayPromise) { #warning such analysis can be optimizer by pre-compiling the code per state machine type var metadata = _asyncStateMachineMetadataProvider.GetMetadata(stateMachine.GetType()); foreach (var variable in metadata.LocalVariables) { if (TaskAwaiterUtils.IsAwaiterType(variable.FieldInfo.FieldType)) { var awaiter = variable.FieldInfo.GetValue(stateMachine); var task = TaskAwaiterUtils.GetTask(awaiter); if (task != null && DelayPromiseAccessor.IsDelayPromise(task)) { delayPromise = task; return(true); } } } delayPromise = null; return(false); }