使用 ApplicationDBContext 的后台线程

Background Thread that uses ApplicaitonDBContext

我正在尝试连接一个后台线程,该线程将每小时从 Active Directory 更新一次数据库。我不确定如何通过当前

    public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            // Add framework services.
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("Connection")));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddSessionStateTempDataProvider();
            services.AddSession();
            services.AddHttpContextAccessor();

            services.AddSingleton(Configuration);
            services.AddScoped<IAppDbRepository, AppDbRepository>();
            services.AddScoped<IActiveDirectoryUtility, ActiveDirectoryUtility>();
            services.AddScoped<IActiveDirectoryManager, ActiveDirectoryManager>();

            services.AddHostedService<LdapManager>();
            services.AddScoped<ILdapManager, LdapManager>();

        }

In the LdapManager class I would like to call the UpdateUsers method every hour:

    public class LdapManager : ILdapManager, IHostedService
    {
        private IConfiguration _configuration = null;
        private Logging _logger;
        private List<string> ldapConnectorForDirectoryEntries = new List<string>();

        public LdapManager(IConfiguration configuration)
        {
            _configuration = configuration;

            UpdateUsers();
            SyncActiveDirectoryUsers();
        }


    public void SyncActiveDirectoryUsers()
        {
            try
            {
                using (var waitHandle = new AutoResetEvent(false))
                {
                    ThreadPool.RegisterWaitForSingleObject(waitHandle, (state, timeout) => { UpdateUsers(); }, null, TimeSpan.FromHours(1), false);
                }
            }
            catch
            {
                throw;
            }
        }
    }

UpdateUsers() 方法应该可以调用 applicationDBContext.SaveChanges() 方法。

如何确保 LDAP 管理器 class 可以使用应用程序数据库上下文?

你可能想要class LdapManager : BackgroundService, ILdapManager

BackgroundService 是 .NET Core 2.1,有一个代码示例可用于 core 2.0

注入 IServiceScopeFactory 并覆盖 Task ExecuteAsync( )、运行 while 循环。

while(!stoppingToken.IsCancellationRequested)
{
    using (var scope = _serviceScopeFactory.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        ...; // do your stuff
    }
    await Task.Delay(myConfig.BackgroundDelay, stoppingToken);
}

这是一个很好的 read about this on MSDN,包括 2.0

的代码示例

用于从 HostedService 访问 ApplicationDbContext

  • DbHostedService
    public class DbHostedService : IHostedService
    {
        private readonly ILogger _logger;

        public DbHostedService(IServiceProvider services,
        ILogger<DbHostedService> logger)
        {
            Services = services;
            _logger = logger;
        }

        public IServiceProvider Services { get; }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Consume Scoped Service Hosted Service is starting.");

            DoWork();

            return Task.CompletedTask;
        }

        private void DoWork()
        {
            _logger.LogInformation("Consume Scoped Service Hosted Service is working.");

            using (var scope = Services.CreateScope())
            {
                var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

                var user = context.Users.LastOrDefault();

                _logger.LogInformation(user?.UserName);
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Consume Scoped Service Hosted Service is stopping.");

            return Task.CompletedTask;
        }
    }
  • 注册DbHostedService

    services.AddHostedService<DbHostedService>();