protected override Task InternalStartAsync(CancellationToken cancellationToken) { return(Task.Run(async() => { Logger.Verbose("Task.Run starting"); while (!cancellationToken.IsCancellationRequested) { // Let the task run var jobResult = await TaskExecContext.ExecAsync(async() => { Logger.Verbose("Before TriggeredJob.Run()"); var result = await TriggeredJob.Run(JobExceptionState, Logger, cancellationToken).ConfigureAwait(false); JobExceptionState.Clear(); Logger.Verbose("After TriggeredJob.Run()"); return result; }, JobExceptionState, this, Logger).ConfigureAwait(false); if (ShouldStop(cancellationToken, jobResult)) { break; } // Now let it handle any exception that occurred if (JobExceptionState.LastException != null) { if (!TriggeredJob.HandleException(JobExceptionState, Logger)) { break; } } // Wait for a trigger to resume await TaskExecContext.ExecAsync(async() => { Logger.Verbose("Before WhenAny(triggers)"); await await Task.WhenAny(TriggeredJob.GetTriggers(cancellationToken)).ConfigureAwait(false); Logger.Verbose("After WhenAny(triggers)"); }, Common.JobExceptionState.None, this, Logger).ConfigureAwait(false); } }, cancellationToken)); }
protected override Task InternalStartAsync(CancellationToken cancellationToken) { return(Task.Run(async() => { Logger.Verbose("Task.Run starting"); while (!cancellationToken.IsCancellationRequested) { // Let the task run var jobResult = await TaskExecContext.ExecAsync(async() => { Logger.Verbose("Before PeriodicJob.Run()"); var result = await PeriodicJob.Run(JobExceptionState, Logger, cancellationToken).ConfigureAwait(false); JobExceptionState.Clear(); Logger.Verbose("After PeriodicJob.Run()"); return result; }, JobExceptionState, this, Logger).ConfigureAwait(false); if (ShouldStop(cancellationToken, jobResult)) { break; } // Now let it handle any exception that occurred if (JobExceptionState.LastException != null) { if (!PeriodicJob.HandleException(JobExceptionState, Logger)) { break; } } await TaskExecContext.ExecAsync(async() => { Logger.Verbose("Before sleep"); await Task.Delay(PeriodicJob.SleepInterval, cancellationToken).ConfigureAwait(false); Logger.Verbose("After sleep"); }, Common.JobExceptionState.None, this, Logger).ConfigureAwait(false); } }, cancellationToken)); }
protected override Task InternalStartAsync(CancellationToken cancellationToken) { return(Task.Run(async() => { bool producerExit = false; var producerTask = Producer.Run(Logger, cancellationToken); Task <bool> consumerTask = Task.FromResult(true); while (!cancellationToken.IsCancellationRequested) { // Wait for consumer first since it regulates the overall data flow bool consumerContinue = await TaskExecContext.ExecAsync(async() => { Logger.Verbose("Before awaiting consumer task"); var result = await consumerTask; Logger.Verbose("After awaiting consumer task"); return result; }, ConsumerExceptionState, this, Logger).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { break; } // Did the producer signal end of data during the last iteration? Logger.Verbose($"Testing producerExit flag: {producerExit}"); if (producerExit) { break; } // If consumer does not want more data, cancel before awaiting producer Logger.Verbose($"Testing consumerContinue flag: {consumerContinue}"); if (!consumerContinue) { Cancel(); } // Wait for producer var producerResult = await TaskExecContext.ExecAsync(async() => { Logger.Verbose("Before awaiting producer task"); var result = await producerTask; Logger.Verbose("After awaiting producer task"); return result; }, ProducerExceptionState, this, Logger).ConfigureAwait(false); // If producer has more data, run it again Logger.Verbose($"Testing producerResult.Continue flag: {producerResult.Continue}"); if (producerResult.Continue) { Logger.Verbose("Run producer job again"); producerTask = Producer.Run(Logger, cancellationToken); } else { // If producer is out of data, set an exit flag and create // fake producer job so consumer can run one more time Logger.Verbose("Prepare for producer exit"); producerExit = true; producerTask = Task.FromResult(default(ProducerResult <TData>)); } // Run consumer Logger.Verbose("Run consumer job again"); consumerTask = Consumer.Run(producerResult.Data, Logger, cancellationToken); } }, cancellationToken)); }