示例#1
0
        // NB: Async void should be avoided; it should only be used for event handlers.Timer.Elapsed is an event handler.So, it's not necessarily wrong here.
        // c.f. http://stackoverflow.com/questions/25007670/using-async-await-inside-the-timer-elapsed-event-handler-within-a-windows-servic
        private async void DoWorkAsync(object group)
        {
            // DoWork needs to be re-entrant as Timer may call the callback before the previous callback has returned.
            // So, because a task may take longer than the period itself, DoWork needs to check if it's still running.
            ShellContext shellContext = _orchardHost.GetOrCreateShellContext(_shellSettings);

            var groupName = group as string ?? "";

            foreach (var task in _tasks[groupName])
            {
                var taskName = task.GetType().FullName;

                using (var scope = shellContext.EnterServiceScope())
                {
                    try
                    {
                        if (_states[task] != BackgroundTaskState.Idle)
                        {
                            return;
                        }

                        lock (_states)
                        {
                            // Ensure Terminate() was not called before
                            if (_states[task] != BackgroundTaskState.Idle)
                            {
                                return;
                            }

                            _states[task] = BackgroundTaskState.Running;
                        }

                        if (Logger.IsEnabled(LogLevel.Information))
                        {
                            Logger.LogInformation("Start processing background task \"{0}\".", taskName);
                        }

                        await task.DoWorkAsync(scope.ServiceProvider, _applicationLifetime.ApplicationStopping);

                        if (Logger.IsEnabled(LogLevel.Information))
                        {
                            Logger.LogInformation("Finished processing background task \"{0}\".", taskName);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (Logger.IsEnabled(LogLevel.Error))
                        {
                            Logger.LogError(ex, $"Error while processing background task \"{taskName}\"");
                        }
                    }
                    finally
                    {
                        lock (_states)
                        {
                            // Ensure Terminate() was not called during the task
                            if (_states[task] != BackgroundTaskState.Stopped)
                            {
                                _states[task] = BackgroundTaskState.Idle;
                            }
                        }
                    }
                }
            }
        }