public void Init(int fromStage, int toStage, System.Action handler) { CoreLogger.LogDebug(LoggerModules.GameApplication, string.Format("requesgted non blocking initialization of modules stages {0} to {1}; total available: {2}", fromStage, toStage, _availableModules.Count)); int pending = 0; ICollection <ITask> tasks = new List <ITask>(); IList <KeyValuePair <Type, IModule> > modulesToRemove = new List <KeyValuePair <Type, IModule> >(); foreach (KeyValuePair <Type, IModule> kvp in _availableModules.Where(kvp => (kvp.Value.Stage >= fromStage) && (kvp.Value.Stage <= toStage))) { //always remember to create a local-scoped variable within foreach loops that use lambdas!!! IModule localModule = kvp.Value; if (!_modules.ContainsKey(localModule.GetType())) { ITask init = localModule.GetInitializer(this); if (init != null) { tasks.Add(init); CoreLogger.LogDebug(LoggerModules.GameApplication, string.Format("located module {0} - starting init", localModule.GetType().Name)); init.Done += result => { if (result.IsOk()) { CoreLogger.LogDebug(LoggerModules.GameApplication, string.Format("successfully done with module {0} ({1}); {2} modules remaining", localModule.GetType().Name, result, pending)); _modules[localModule.GetType()] = localModule; } else { CoreLogger.LogDebug(LoggerModules.GameApplication, string.Format("failed with module {0} ({1}); {2} modules remaining", localModule.GetType().Name, result, pending)); _failedModules[localModule.GetType()] = localModule; } }; } else { CoreLogger.LogError(LoggerModules.GameApplication, string.Format("failed to retrieve initializer for module {0}", localModule.GetType().Name)); _failedModules[localModule.GetType()] = localModule; } } } _taskFactory.Parallelize(tasks).Start(result => { handler(); }); foreach (KeyValuePair <Type, IModule> toRemove in modulesToRemove) { _availableModules.Remove(toRemove); } }