0
votes

I'm currently building a Windows Service which creates a thread which runs every 30 minutes and updates a few fields on some entities which meet a criteria (and in the future, I want to add further threads to do other things, eg run one every 24 hours, one every week, etc). The service will get and update it's data using services which are already used by a web application and are injected using Ninject (along with the DbContext) - this all works fine using the InRequestScope() binding.

However, I've been thinking about how best to approach this using a Windows Service. Essentially, once the service starts and the thread is created, it runs continuously (aside from sleeping every 30 minutes) - and only ever stops if the Windows Service stops or the process gets terminated. My initial thought was to inject my DbContext and services using the InThreadScope() option of Ninject - so I'd have a DbContext for each thread. But is it generally good practice to have a DbContext that has such a long lifetime? This DbContext could be sitting there for weeks without being disposed - and I have a sneaking suspicion that this isn't such a a good idea (memory leaks, etc).

But if not, what is the best way to handle this scenario. I could create a new DbContext each time the thread runs, but how would I set up the Ninject bindings? Currently they're defined as:

        Bind<IDbContext>().To<EnterpriseDbContext>().InThreadScope();
        Bind<IUserRepository>().To<UserRepository>().InThreadScope();
        // Etc

So I'm not entirely sure how I would structure this to create a new one within the thread. I looked at InTransientScope(), but this is causing my services to use different versions of the context, so my changes never get saved.

This seems like it would be such a common scenario - so would be great to hear anyone else's view.

2

2 Answers

2
votes

Instead of creating threads that sleep until the next run you can use Quartz.Net as scheduling mechanism. In combination with InCallScope from the NamedScope extension you have the same behavior as InRequestScope of a WebService. Additionally you get a superior scheduling than just spawning threads that run in intervals. You can specify when they shall run using Cron Job syntax.

See:

0
votes

I particularly like @Remo's suggestions, and will be trying these on the next project I work on. However, I eventually solved the problem by using a custom InScope implementation - but setting a custom object that there should be scope to each time the thread ran. This way the context was recreated every time it ran (as disposed once the scope object was disposed).