internal static void PlaceFileIntoQueue() { if (!_servicesFlags.TryLock("PlaceFileIntoQueue")) { return; } try { using (var db = new DB.DataContext()) { db.DataContext.StoredProcedure <object>("FileManager_PlaceFileIntoQueue"); } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Ошибка заполнения очереди удаления", null, ex); } finally { _servicesFlags.ReleaseLock("PlaceFileIntoQueue"); } }
internal static void CheckRemovedFiles(bool isStart) { if (!_servicesFlags.TryLock("CheckRemovedFiles")) { return; } bool isFinalized = false; int countFiles = 0; try { if (isStart) { _servicesFlags.ReleaseLock("CheckRemovedFilesMax"); TasksManager.SetTask(typeof(FileManager).FullName + "_" + nameof(CheckRemovedFiles) + "_minutely5", Cron.MinuteInterval(5), () => CheckRemovedFiles(false)); _thisModule?.RegisterEvent(EventType.Info, "Запуск регулярной задачи проверки файлов.", null); } var executionTimeLimit = new TimeSpan(0, 4, 30); var dateStart = DateTime.Now; int idFileMax = _checkRemovedFilesMax; var rootDirectory = _thisModule?.AppCore?.ApplicationWorkingFolder; using (var db = new DB.DataContext()) { while ((DateTime.Now - dateStart) < executionTimeLimit) { var filesQuery = db.File.AsNoTracking().Where(x => !x.IsRemoved && !x.IsRemoving && x.IdFile > idFileMax).OrderBy(x => x.IdFile).Take(5000); var filesList = filesQuery.ToList(); if (filesList.Count == 0) { isFinalized = true; break; } var updateList = new List <DB.File>(); filesList.ForEach(file => { try { if (!File.Exists(Path.Combine(rootDirectory, file.PathFile))) { file.IsRemoving = true; updateList.Add(file); } } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } catch { } idFileMax = file.IdFile; }); if (updateList.Count > 0) { using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew)) { db.File.InsertOrDuplicateUpdate(updateList, new UpsertField(nameof(DB.File.IsRemoved)), new UpsertField(nameof(DB.File.IsRemoving))); scope.Commit(); } countFiles += updateList.Count; } _checkRemovedFilesMax = idFileMax; } } if (isFinalized) { TasksManager.RemoveTask(typeof(FileManager).FullName + "_" + nameof(CheckRemovedFiles) + "_minutely5"); //TasksManager.SetTask(typeof(FileManager).FullName + "_" + nameof(CheckRemovedFiles) + "_0", DateTime.Now.AddHours(2), () => CheckRemovedFiles(true)); TasksManager.SetTask(typeof(FileManager).FullName + "_" + nameof(CheckRemovedFiles) + "_0", DateTime.Now.AddMinutes(1), () => CheckRemovedFiles(true)); _thisModule?.RegisterEvent(EventType.Info, "Удаление регулярной задачи проверки файлов.", null); } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Ошибка заполнения очереди удаления", null, ex); } finally { _servicesFlags.ReleaseLock("CheckRemovedFiles"); if (countFiles > 0) { _thisModule?.RegisterEvent(EventType.Info, "Проверка удаленных файлов", $"На удаление помечено {countFiles} файлов.", null); } } }
internal static void RemoveMarkedFiles() { if (!_servicesFlags.TryLock("RemoveMarkedFiles")) { return; } int countFiles = 0; try { var executionTimeLimit = TimeSpan.FromSeconds(50); var dateStart = DateTime.Now; int idFileMax = 0; var rootDirectory = _thisModule?.AppCore?.ApplicationWorkingFolder; using (var db = new DB.DataContext()) { while ((DateTime.Now - dateStart) < executionTimeLimit) { var fileToRemoveQuery = (from FileRemoveQueue in db.FileRemoveQueue join File in db.File.AsNoTracking() on FileRemoveQueue.IdFile equals File.IdFile into File_j from File in File_j.DefaultIfEmpty() where FileRemoveQueue.IdFile > idFileMax orderby FileRemoveQueue.IdFile ascending select new { FileRemoveQueue, File }).Take(100); var fileToRemoveList = fileToRemoveQuery.ToList(); if (fileToRemoveList.Count == 0) { break; } var removeList = new List <int>(); var updateList = new List <DB.File>(); fileToRemoveList.ForEach(row => { try { if (row.File == null) { removeList.Add(row.FileRemoveQueue.IdFile); } else { if (File.Exists(Path.Combine(rootDirectory, row.File.PathFile))) { File.Delete(Path.Combine(rootDirectory, row.File.PathFile)); } removeList.Add(row.FileRemoveQueue.IdFile); row.File.IsRemoving = false; row.File.IsRemoved = true; updateList.Add(row.File); } } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } catch { } idFileMax = row.FileRemoveQueue.IdFile; }); if (removeList.Count > 0 || updateList.Count > 0) { using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew)) { if (removeList.Count > 0) { db.FileRemoveQueue.Where(x => removeList.Contains(x.IdFile)).Delete(); db.SaveChanges <DB.FileRemoveQueue>(); } if (updateList.Count > 0) { if (updateList.Any(x => x.IsRemoving || !x.IsRemoved)) { throw new Exception("Флаги удаления сбросились!"); } db.File.InsertOrDuplicateUpdate(updateList, new UpsertField(nameof(DB.File.IsRemoved)), new UpsertField(nameof(DB.File.IsRemoving))); } scope.Commit(); } countFiles += updateList.Count; } } } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Ошибка заполнения очереди удаления", null, ex); } finally { _servicesFlags.ReleaseLock("RemoveMarkedFiles"); if (countFiles > 0) { _thisModule?.RegisterEvent(EventType.Info, "Удаление файлов", $"Удалено {countFiles} файлов.", null); } } }