public bool RemoveMark(params int[] fileList) { if (fileList.IsNullOrEmpty()) { return(true); } try { using (var db = new Db.DataContext()) using (var scope = db.CreateScope(TransactionScopeOption.Required)) { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).In(fileList, x => x.IdFile); if (query.ForEach(file => { file.IsRemoving = true; }) > 0) { db.SaveChanges(); scope.Complete(); } } return(true); } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка удаления файлов с истекшим сроком", null, null, ex); return(false); } }
public bool RemoveCompletely(params int[] fileList) { if (fileList.IsNullOrEmpty()) { return(true); } try { var rootDirectory = AppCore.ApplicationWorkingFolder; using (var db = new Db.DataContext()) using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew)) { var query = db.File.Where(x => !x.IsRemoved && !x.IsRemoving).In(fileList, x => x.IdFile); if (query.ForEach(file => { try { var pathCombined = Path.Combine(rootDirectory, file.PathFile); if (File.Exists(pathCombined)) { File.Delete(pathCombined); } } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } catch { } db.File.Remove(file); }) > 0) { db.SaveChanges(); scope.Complete(); } } return(true); } catch (Exception ex) { this.RegisterEvent(EventType.Error, "Ошибка удаления файлов с истекшим сроком", null, null, ex); return(false); } }
internal static void CheckRemovedFiles() { // Не запускать не машине разработчика, иначе может быть так, что при подключении базе на удаленном сервере файлы физически останутся, а из базы будут удалены. if (Debug.IsDeveloper) { return; } if (!_servicesFlags.TryLock("CheckRemovedFiles")) { return; } bool isFinalized = false; int countFiles = 0; int checkRemovedFilesMax = 0; var startTime = DateTime.Now.Date.AddHours(3); try { if (_thisModule?.AppCore?.GetState() != CoreComponentState.Started) { return; } if (!_thisModule.GetConfiguration <FileManagerConfiguration>().IsCheckRemovedFiles) { return; } var journalResult = _thisModule.GetJournal(); if (!journalResult.IsSuccess) { Debug.WriteLine("Ошибка получения журнала файлового менеджера."); _thisModule?.RegisterEvent(EventType.Error, "Проверка удаленных файлов", $"Ошибка получения журнала файлового менеджера: {journalResult.Message}", null); return; } var dbAccessor = _thisModule.AppCore.Get <Journaling.DB.JournalingManagerDatabaseAccessor>(); using (var dbJournal = new Journaling.DB.DataContext()) { var range = new DateRange(DateTime.Now.Date, DateTime.Now.Date.AddDays(1)); var queryBase = dbAccessor.CreateQueryJournalData(dbJournal).Where(x => x.JournalName.IdJournal == journalResult.Result.IdJournal && x.JournalData.DateEvent >= range.Start && x.JournalData.DateEvent < range.End); if (queryBase.Where(x => x.JournalData.EventCode == EventCodeCheckRemovedFilesExecuted).Count() > 0) { return; } var lastRunInfo = queryBase.Where(x => x.JournalData.EventCode == EventCodeCheckRemovedFilesInfo).OrderByDescending(x => x.JournalData.IdJournalData).FirstOrDefault(); if (lastRunInfo == null) { if (DateTime.Now < startTime) { return; } _thisModule?.RegisterEvent(EventType.Info, "Проверка удаленных файлов", "Запуск регулярной задачи проверки файлов."); } else if (int.TryParse(lastRunInfo.JournalData.EventInfoDetailed, out int checkRemovedFilesMaxTmp)) { checkRemovedFilesMax = checkRemovedFilesMaxTmp; } } 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). Select(x => new Db.File() { IdFile = x.IdFile, PathFile = x.PathFile, IsRemoving = x.IsRemoving, IsRemoved = x.IsRemoved }). 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. UpsertRange(updateList). AllowIdentityMatch(). On(x => x.IdFile). WhenMatched((xDb, xIns) => new Db.File() { IsRemoved = xIns.IsRemoved, IsRemoving = xIns.IsRemoving }). Run(); scope.Complete(); } countFiles += updateList.Count; } checkRemovedFilesMax = idFileMax; } } if (!isFinalized) { _thisModule?.RegisterEvent(EventType.Info, EventCodeCheckRemovedFilesInfo, "Проверка удаленных файлов", checkRemovedFilesMax.ToString()); } else { _thisModule?.RegisterEvent(EventType.Info, EventCodeCheckRemovedFilesExecuted, "Проверка удаленных файлов", "Удаление регулярной задачи проверки файлов."); } } catch (ThreadAbortException) { } catch (Exception ex) { _thisModule?.RegisterEvent(EventType.Error, "Проверка удаленных файлов", "Ошибка заполнения очереди удаления", ex); } finally { _servicesFlags.ReleaseLock("CheckRemovedFiles"); if (countFiles > 0) { _thisModule?.RegisterEvent(EventType.Info, "Проверка удаленных файлов", $"На удаление помечено {countFiles} файлов.", null); } } }
internal static void RemoveMarkedFiles() { if (_thisModule?.AppCore?.GetState() != CoreComponentState.Started) { return; } 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 { var pathCombined = Path.Combine(rootDirectory, row.File.PathFile); if (File.Exists(pathCombined)) { File.Delete(pathCombined); } 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) { var query = db.FileRemoveQueue.In(removeList, x => x.IdFile); db.FileRemoveQueue.RemoveRange(query); db.SaveChanges <Db.FileRemoveQueue>(); } if (updateList.Count > 0) { if (updateList.Any(x => x.IsRemoving || !x.IsRemoved)) { throw new Exception("Флаги удаления сбросились!"); } db.File. UpsertRange(updateList). AllowIdentityMatch(). On(x => x.IdFile). WhenMatched((xDb, xIns) => new Db.File() { IsRemoved = xIns.IsRemoved, IsRemoving = xIns.IsRemoving }). Run(); } scope.Complete(); } 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); } } }