Hi I am using Simple Injector and I am trying to implement a scheduler service which calls command(s) at a programmable regular frequency. My design decisions are below:
1) I have a service that runs a background thread and resolves from the container ICommandHandler<SyncExternalDataCommand>.Handle(someParameter) and calls the command handle method.
RegisterCommandAsBusinessUnitCronJob will be called for each BusinessUnit with the ID passed as a parameter on each call. We could also implement RegistercommandAsCustomerContactCronJob to loop through customer records. 
Is it ok to design the scheduler in this way with a background thread?
2) I have tried to keep the coupling between the composition root container and the scheduler to a minimum.
An approach with Action helper delegates helps to keep the code in the composition root section as opposed to within the service. By using a different design, could this coupling be reduced further or is this coupling acceptable?
Code is below (it is yet to be made thread-safe), comments on the design decisions above and improvements/redesign are very welcome.
Thanks, Chris
Bootstrap of the container
void Register(Container container)
{
    container.RegisterSingle<IUnitOfWorkFactory>(
        new UnitOfWorkFactory(container));
    container.RegisterLifetimeScope<IUnitOfWork, UnitOfWork>();
    container.RegisterSingle<ILogger, Logger>();
    container.RegisterSingle<ICronJobService, CronJobService>();
    container.Register<ICommandHandler<SyncExternalDataCommand>, 
        SyncExternalDataCommandHandler>();
    var cronJobService = container.GetInstance<ICronJobService>();
    cronJobService.RegisterCommandAsBusinessUnitCronJob("* 1 * * *",
        (Int32 id) =>
        {
            var command = new SyncExternalDataCommand()
            {
                businessUnitId = id
            };
            using (container.BeginLifetimeScope()) 
            { 
                // handler must be resolved INSIDE the scope. 
                var handler =
         container.GetInstance<ICommandHandler<SyncExternalDataCommand>>(); 
                handler.Handle(command); 
            }
        }
    );
}
Scheduler service
// to be instantiated as a singleton by IoC container
public class CronJobService : ICronJobService
{
    // this dictionary is for tasks that will be called with 
    // the business unit primary key (Int32).
    private cronJobs = new Dictionary<Action<Int32>, string>();
    public void RegisterCommandAsBusinessUnitCronJob(
        string cronString, Action<Int32> commandFactory)
    {
        cronJobs.Add(commandFactory, cronString);
    }
    // this below is called when we are running a task
    protected static bool RunCreateAndHandleThread(
        object parameter)
    {
        var jobParameters = (ThreadJobParameters)parameter;
        if (!cancellationTokenSource.IsCancellationRequested)
        {
            // we will need to construct new graph with a
            // proxy command
            jobParameters.helper(jobParameters.businessUnitId);
        }
        return true;
    }
    protected static void SomeBackgroundLoop(
        RunHandlePollingLoopParameters parameters)
    {
        IUnitOfWork unitOfWork = 
            parameters.unitOfWorkFactory.CreateUnitOfWork();
        using (unitOfWork)
        {
            var businessUnits = 
                unitOfWork.BusinessUnitRepository.Get();
            // loop through cron jobs and business units
            foreach (var helperFactory in parameters.cronJobs.Keys)
            {
                // its time to run this job...
                if (isTimeToRunCronjob) 
                {
                    var jobParameters = new ThreadJobParameters
                    {
                        helper = helperFactory,
                        businessUnitId = businessUnit.Id
                    };
                    Task.Factory.StartNew<bool>(
                        RunCreateAndHandleThread, 
                        jobParameters, 
                        CronJobService.cancellationTokenSource.Token, 
                        TaskCreationOptions.LongRunning, 
                        TaskScheduler.Default);
                }
            }
        }
    }
}
 
     
    