Background Thread that uses ApplicaitonDBContext












1















I am trying to wire up a background thread that will update the database once an hour from Active Directory. I am not sure how to pass the current



    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;
}
}
}


The UpdateUsers() method should be able to call the applicationDBContext.SaveChanges() method.



How can I ensure that the LDAP manger class can use the Application DB context?










share|improve this question























  • You need to do special stuff to have a long running timer like that in a asp.net environment

    – Scott Chamberlain
    Nov 23 '18 at 22:03











  • public LdapManager(IConfiguration configuration, ApplicationDbContext appContext) ?

    – Henk Holterman
    Nov 24 '18 at 0:10











  • @ScottChamberlain - AddHostedService is special stuff.

    – Henk Holterman
    Nov 24 '18 at 0:11
















1















I am trying to wire up a background thread that will update the database once an hour from Active Directory. I am not sure how to pass the current



    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;
}
}
}


The UpdateUsers() method should be able to call the applicationDBContext.SaveChanges() method.



How can I ensure that the LDAP manger class can use the Application DB context?










share|improve this question























  • You need to do special stuff to have a long running timer like that in a asp.net environment

    – Scott Chamberlain
    Nov 23 '18 at 22:03











  • public LdapManager(IConfiguration configuration, ApplicationDbContext appContext) ?

    – Henk Holterman
    Nov 24 '18 at 0:10











  • @ScottChamberlain - AddHostedService is special stuff.

    – Henk Holterman
    Nov 24 '18 at 0:11














1












1








1








I am trying to wire up a background thread that will update the database once an hour from Active Directory. I am not sure how to pass the current



    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;
}
}
}


The UpdateUsers() method should be able to call the applicationDBContext.SaveChanges() method.



How can I ensure that the LDAP manger class can use the Application DB context?










share|improve this question














I am trying to wire up a background thread that will update the database once an hour from Active Directory. I am not sure how to pass the current



    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;
}
}
}


The UpdateUsers() method should be able to call the applicationDBContext.SaveChanges() method.



How can I ensure that the LDAP manger class can use the Application DB context?







asp.net-mvc multithreading asp.net-core-2.0






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 23 '18 at 21:44









codegcodeg

831115




831115













  • You need to do special stuff to have a long running timer like that in a asp.net environment

    – Scott Chamberlain
    Nov 23 '18 at 22:03











  • public LdapManager(IConfiguration configuration, ApplicationDbContext appContext) ?

    – Henk Holterman
    Nov 24 '18 at 0:10











  • @ScottChamberlain - AddHostedService is special stuff.

    – Henk Holterman
    Nov 24 '18 at 0:11



















  • You need to do special stuff to have a long running timer like that in a asp.net environment

    – Scott Chamberlain
    Nov 23 '18 at 22:03











  • public LdapManager(IConfiguration configuration, ApplicationDbContext appContext) ?

    – Henk Holterman
    Nov 24 '18 at 0:10











  • @ScottChamberlain - AddHostedService is special stuff.

    – Henk Holterman
    Nov 24 '18 at 0:11

















You need to do special stuff to have a long running timer like that in a asp.net environment

– Scott Chamberlain
Nov 23 '18 at 22:03





You need to do special stuff to have a long running timer like that in a asp.net environment

– Scott Chamberlain
Nov 23 '18 at 22:03













public LdapManager(IConfiguration configuration, ApplicationDbContext appContext) ?

– Henk Holterman
Nov 24 '18 at 0:10





public LdapManager(IConfiguration configuration, ApplicationDbContext appContext) ?

– Henk Holterman
Nov 24 '18 at 0:10













@ScottChamberlain - AddHostedService is special stuff.

– Henk Holterman
Nov 24 '18 at 0:11





@ScottChamberlain - AddHostedService is special stuff.

– Henk Holterman
Nov 24 '18 at 0:11












2 Answers
2






active

oldest

votes


















1














You probably want class LdapManager : BackgroundService, ILdapManager



BackgroundService is .NET Core 2.1, there is a code sample available for core 2.0



Inject IServiceScopeFactory and override Task ExecuteAsync( ), run a while loop there.



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


And here is a good read about this on MSDN, including the code sample for 2.0






share|improve this answer


























  • do you have a link to the Background Service example for .net core 2.1?

    – codeg
    Nov 26 '18 at 16:25





















1














For accessing ApplicationDbContext from HostedService.





  • 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;
    }
    }



  • Register DbHostedService



    services.AddHostedService<DbHostedService>();







share|improve this answer
























  • You would almost always want a Task DoWork()

    – Henk Holterman
    Nov 29 '18 at 17:53











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453235%2fbackground-thread-that-uses-applicaitondbcontext%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














You probably want class LdapManager : BackgroundService, ILdapManager



BackgroundService is .NET Core 2.1, there is a code sample available for core 2.0



Inject IServiceScopeFactory and override Task ExecuteAsync( ), run a while loop there.



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


And here is a good read about this on MSDN, including the code sample for 2.0






share|improve this answer


























  • do you have a link to the Background Service example for .net core 2.1?

    – codeg
    Nov 26 '18 at 16:25


















1














You probably want class LdapManager : BackgroundService, ILdapManager



BackgroundService is .NET Core 2.1, there is a code sample available for core 2.0



Inject IServiceScopeFactory and override Task ExecuteAsync( ), run a while loop there.



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


And here is a good read about this on MSDN, including the code sample for 2.0






share|improve this answer


























  • do you have a link to the Background Service example for .net core 2.1?

    – codeg
    Nov 26 '18 at 16:25
















1












1








1







You probably want class LdapManager : BackgroundService, ILdapManager



BackgroundService is .NET Core 2.1, there is a code sample available for core 2.0



Inject IServiceScopeFactory and override Task ExecuteAsync( ), run a while loop there.



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


And here is a good read about this on MSDN, including the code sample for 2.0






share|improve this answer















You probably want class LdapManager : BackgroundService, ILdapManager



BackgroundService is .NET Core 2.1, there is a code sample available for core 2.0



Inject IServiceScopeFactory and override Task ExecuteAsync( ), run a while loop there.



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


And here is a good read about this on MSDN, including the code sample for 2.0







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 29 '18 at 17:51

























answered Nov 24 '18 at 0:21









Henk HoltermanHenk Holterman

209k22232404




209k22232404













  • do you have a link to the Background Service example for .net core 2.1?

    – codeg
    Nov 26 '18 at 16:25





















  • do you have a link to the Background Service example for .net core 2.1?

    – codeg
    Nov 26 '18 at 16:25



















do you have a link to the Background Service example for .net core 2.1?

– codeg
Nov 26 '18 at 16:25







do you have a link to the Background Service example for .net core 2.1?

– codeg
Nov 26 '18 at 16:25















1














For accessing ApplicationDbContext from HostedService.





  • 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;
    }
    }



  • Register DbHostedService



    services.AddHostedService<DbHostedService>();







share|improve this answer
























  • You would almost always want a Task DoWork()

    – Henk Holterman
    Nov 29 '18 at 17:53
















1














For accessing ApplicationDbContext from HostedService.





  • 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;
    }
    }



  • Register DbHostedService



    services.AddHostedService<DbHostedService>();







share|improve this answer
























  • You would almost always want a Task DoWork()

    – Henk Holterman
    Nov 29 '18 at 17:53














1












1








1







For accessing ApplicationDbContext from HostedService.





  • 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;
    }
    }



  • Register DbHostedService



    services.AddHostedService<DbHostedService>();







share|improve this answer













For accessing ApplicationDbContext from HostedService.





  • 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;
    }
    }



  • Register DbHostedService



    services.AddHostedService<DbHostedService>();








share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 28 '18 at 5:20









Tao ZhouTao Zhou

6,41331331




6,41331331













  • You would almost always want a Task DoWork()

    – Henk Holterman
    Nov 29 '18 at 17:53



















  • You would almost always want a Task DoWork()

    – Henk Holterman
    Nov 29 '18 at 17:53

















You would almost always want a Task DoWork()

– Henk Holterman
Nov 29 '18 at 17:53





You would almost always want a Task DoWork()

– Henk Holterman
Nov 29 '18 at 17:53


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453235%2fbackground-thread-that-uses-applicaitondbcontext%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen