public CourseSecGAOperators(GaTask task)
        {
            _dbContext = new DatabaseContext();
            _task = task;
            //relationDict = new Dictionary<KeyValuePair<ObjectId, ObjectId>, Relation.RelationType>();
            _relationsCache = new Cache<KeyValuePair<ObjectId, ObjectId>, Relation.RelationType?>();

            //currentLOsSetKnowledges = new HashSet<Knowledge>();

            //foreach (var sourceLearningObject in _task.SourceLearningObjects)
            //{
            //    foreach (var prerequisite in sourceLearningObject.Prerequisites)
            //    {
            //        var knowledge = dbContext.Ontology.Find(x => x.Id == prerequisite.KnowledgeId).SingleOrDefaultAsync().Result;
            //        currentLOsSetKnowledges.Add(knowledge);
            //    }

            //    foreach (var outcome in sourceLearningObject.Outcomes)
            //    {
            //        var knowledge = dbContext.Ontology.Find(x => x.Id == outcome.KnowledgeId).SingleOrDefaultAsync().Result;
            //        currentLOsSetKnowledges.Add(knowledge);
            //    }
            //}
        }
        public async Task<ObjectId> TaskRunAsync(GaTask gaTask)
        {
            BackgroundWorker bw = new BackgroundWorker
            {
                WorkerSupportsCancellation = true,
                WorkerReportsProgress = true
            };

            bw.DoWork += bw_DoWork;
            bw.ProgressChanged += bw_ProgressChanged;
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;

            DatabaseContext dbContext = new DatabaseContext();
            gaTask.LaunchTime = DateTime.Now;
            gaTask.State = TaskState.Launched;
            await dbContext.gaTasks.InsertOneAsync(gaTask);

            bw.RunWorkerAsync(gaTask);
            //Console.WriteLine("Task " + gaTask.Id + " launched");
            Workers.Add(gaTask.Id, bw);
            return gaTask.Id;
        }
        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            DatabaseContext dbContext = new DatabaseContext();
            int percentage = e.ProgressPercentage;
            ObjectId id = (ObjectId)e.UserState;

            var filter = Builders<GaTask>.Filter.Eq(s => s.Id, id);
            var update = Builders<GaTask>.Update.Set(s => s.ProgressPercent, percentage);
            dbContext.gaTasks.UpdateOneAsync(filter, update);
        }
        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            GaTask task = (GaTask)e.Result;

            if (task.State == TaskState.Cancelled)
            {
                //Console.WriteLine("Task " + task.Id + " cancelled");
                DatabaseContext dbContext = new DatabaseContext();
                ObjectId id = task.Id;

               
                //var update = Builders<GaTask>.Update.Set(s => s.State, TaskState.Cancelled);
                //dbContext.gaTasks.UpdateOneAsync(filter, update);
                var filter = Builders<GaTask>.Filter.Eq(s => s.Id, id);
                dbContext.gaTasks.ReplaceOneAsync(filter, task);
                //var updateWhole = Builders<GaTask>.Update.Set(s => s, task);
                //dbContext.gaTasks.FindOneAndUpdateAsync(filter, updateWhole);
                Workers.Remove(id);
            }
            else if (task.State == TaskState.Error)
            {
                //Console.WriteLine("Error occured during task " + task.Id + " working");
                DatabaseContext dbContext = new DatabaseContext();
                ObjectId id = task.Id;

                //var filter = Builders<GaTask>.Filter.Eq(s => s.Id, id);
                //var update = Builders<GaTask>.Update
                //    .Set(s => s.State, TaskState.Error)
                //    .Set(s => s.ErrorMessage, task.ErrorMessage);
                //dbContext.gaTasks.UpdateOneAsync(filter, update);

                var filter = Builders<GaTask>.Filter.Eq(s => s.Id, id);
                dbContext.gaTasks.ReplaceOneAsync(filter, task);
                //var updateWhole = Builders<GaTask>.Update.Set(s => s, task);
                //dbContext.gaTasks.FindOneAndUpdateAsync(filter, updateWhole);
                Workers.Remove(id);
            }
            else
            {
                ////Console.WriteLine("Task " + task.Id + " finished");
                //DatabaseContext dbContext = new DatabaseContext();
                //ObjectId id = task.Id;

                //var filter = Builders<GaTask>.Filter.Eq(s => s.Id, id);
                //dbContext.gaTasks.ReplaceOneAsync(filter, task);

                DatabaseContext dbContext = new DatabaseContext();
                var filter = Builders<GaTask>.Filter.Eq(s => s.Id, task.Id);
                var update = Builders<GaTask>.Update
                    .Set(s => s.State, TaskState.Finished)
                    .Set(s => s.AverageFFvalues, task.AverageFFvalues)
                    .Set(s => s.WorstFfValues, task.WorstFfValues)
                    .Set(s => s.BestFfValues, task.BestFfValues)
                    .Set(s => s.FinishTime, task.FinishTime)
                    .Set(s => s.ResultLearningObjects, task.ResultLearningObjects);

                var v = dbContext.gaTasks.UpdateOneAsync(filter, update).Result;

                Workers.Remove(task.Id);
            }
        }