Exemplo n.º 1
0
        public static Task DelayedAsync(TimeSpan delay, Func <Task> action, CancellationToken cancellationToken = default)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.CompletedTask);
            }

            return(Task.Run(async() => {
                if (delay.Ticks > 0)
                {
                    await SystemClock.SleepAsync(delay, cancellationToken).AnyContext();
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                await action().AnyContext();
            }, cancellationToken));
        }
Exemplo n.º 2
0
        private async Task RunCallbackAsync()
        {
            bool isTraceLogLevelEnabled = _logger.IsEnabled(LogLevel.Trace);

            if (_isRunning)
            {
                if (isTraceLogLevelEnabled)
                {
                    _logger.LogTrace("Exiting run callback because its already running, will run again immediately.");
                }

                _shouldRunAgainImmediately = true;
                return;
            }

            if (isTraceLogLevelEnabled)
            {
                _logger.LogTrace("Starting RunCallbackAsync");
            }
            using (await _lock.LockAsync().AnyContext()) {
                if (_isRunning)
                {
                    if (isTraceLogLevelEnabled)
                    {
                        _logger.LogTrace("Exiting run callback because its already running, will run again immediately.");
                    }

                    _shouldRunAgainImmediately = true;
                    return;
                }

                _last = SystemClock.UtcNow;
            }

            try {
                _isRunning = true;
                DateTime?next = null;

                try {
                    next = await _timerCallback().AnyContext();
                } catch (Exception ex) {
                    if (_logger.IsEnabled(LogLevel.Error))
                    {
                        _logger.LogError(ex, "Error running scheduled timer callback: {Message}", ex.Message);
                    }

                    _shouldRunAgainImmediately = true;
                }

                if (_minimumInterval > TimeSpan.Zero)
                {
                    if (isTraceLogLevelEnabled)
                    {
                        _logger.LogTrace("Sleeping for minimum interval: {Interval}", _minimumInterval);
                    }
                    await SystemClock.SleepAsync(_minimumInterval).AnyContext();

                    if (isTraceLogLevelEnabled)
                    {
                        _logger.LogTrace("Finished sleeping");
                    }
                }

                var nextRun = SystemClock.UtcNow.AddMilliseconds(10);
                if (_shouldRunAgainImmediately || next.HasValue && next.Value <= nextRun)
                {
                    ScheduleNext(nextRun);
                }
                else if (next.HasValue)
                {
                    ScheduleNext(next.Value);
                }
            } catch (Exception ex) {
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError(ex, "Error running schedule next callback: {Message}", ex.Message);
                }
            } finally {
                _isRunning = false;
                _shouldRunAgainImmediately = false;
            }

            if (isTraceLogLevelEnabled)
            {
                _logger.LogTrace("Finished RunCallbackAsync");
            }
        }
Exemplo n.º 3
0
        private async Task RunCallbackAsync()
        {
            bool isTraceLogLevelEnabled = _logger.IsEnabled(0);

            if (_isRunning)
            {
                if (isTraceLogLevelEnabled)
                {
                    _logger.LogTrace("Exiting run callback because its already running, will run again immediately.", Array.Empty <object>());
                }
                _shouldRunAgainImmediately = true;
            }
            else
            {
                if (isTraceLogLevelEnabled)
                {
                    LoggerExtensions.LogTrace(_logger, "Starting RunCallbackAsync", Array.Empty <object>());
                }
                using (await _lock.LockAsync().AnyContext())
                {
                    if (_isRunning)
                    {
                        if (isTraceLogLevelEnabled)
                        {
                            _logger.LogTrace("Exiting run callback because its already running, will run again immediately.", Array.Empty <object>());
                        }
                        _shouldRunAgainImmediately = true;
                        return;
                    }
                    _last = SystemClock.UtcNow;
                }
                try
                {
                    _isRunning = true;
                    DateTime? next = null;
                    Stopwatch sw   = Stopwatch.StartNew();
                    try
                    {
                        next = await _timerCallback().AnyContext();
                    }
                    catch (Exception ex)
                    {
                        if (_logger.IsEnabled(LogLevel.Error))
                        {
                            LoggerExtensions.LogError(_logger, ex, "Error running scheduled timer callback: {Message}", new object[1]
                            {
                                ex.Message
                            });
                        }
                        _shouldRunAgainImmediately = true;
                    }
                    finally
                    {
                        sw.Stop();
                        if (isTraceLogLevelEnabled)
                        {
                            LoggerExtensions.LogTrace(_logger, "Callback took: {Elapsed:g}", new object[1]
                            {
                                sw.Elapsed
                            });
                        }
                    }
                    if (_minimumInterval > TimeSpan.Zero)
                    {
                        if (isTraceLogLevelEnabled)
                        {
                            LoggerExtensions.LogTrace(_logger, "Sleeping for minimum interval: {Interval:g}", new object[1]
                            {
                                _minimumInterval
                            });
                        }
                        await SystemClock.SleepAsync(_minimumInterval, default(CancellationToken)).AnyContext();

                        if (isTraceLogLevelEnabled)
                        {
                            LoggerExtensions.LogTrace(_logger, "Finished sleeping", Array.Empty <object>());
                        }
                    }
                    DateTime dateTime = SystemClock.UtcNow.AddMilliseconds(10.0);
                    if (_shouldRunAgainImmediately || (next.HasValue && next.Value <= dateTime))
                    {
                        ScheduleNext(dateTime);
                    }
                    else if (next.HasValue)
                    {
                        ScheduleNext(next.Value);
                    }
                }
                catch (Exception ex2)
                {
                    if (_logger.IsEnabled(LogLevel.Error))
                    {
                        LoggerExtensions.LogError(_logger, ex2, "Error running schedule next callback: {Message}", new object[1]
                        {
                            ex2.Message
                        });
                    }
                }
                finally
                {
                    _isRunning = false;
                    _shouldRunAgainImmediately = false;
                }
                if (isTraceLogLevelEnabled)
                {
                    LoggerExtensions.LogTrace(_logger, "Finished RunCallbackAsync", Array.Empty <object>());
                }
            }
        }