private static void SaveChanges(FileRecord fileRecord) { fileRecord.LastModified = DateTime.Now; fileRecord.ReadOnlyElementsList = fileRecord.RecordSet.Index.GetValues(); fileRecord.CachedTable = null; fileRecord.Dirty = false; XmlDataProviderDocumentWriter.Save(fileRecord); }
private static void DoSave(FileRecord fileRecord) { XDocument xDocument = new XDocument(); XElement root = new XElement(GetRootElementName(fileRecord.ElementName)); xDocument.Add(root); var recordSet = fileRecord.RecordSet; List<XElement> elements = new List<XElement>(recordSet.Index.GetValues()); string key = fileRecord.FilePath.ToLowerInvariant(); Func<IEnumerable<XElement>, IOrderedEnumerable<XElement>> orderer; if (TryGetFileOrderer(out orderer, fileRecord.FilePath)) { var orderedElements = orderer(elements); orderedElements.ForEach(root.Add); } else { elements.ForEach(root.Add); } Exception thrownException = null; // Writing the file in the "catch" block in order to prevent chance of corrupting the file by experiencing ThreadAbortException. try { } finally { try { // Saving to temp file and file move to prevent broken saves XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.CheckCharacters = false; xmlWriterSettings.Indent = true; using (XmlWriter xmlWriter = XmlWriter.Create(fileRecord.TempFilePath, xmlWriterSettings)) { xDocument.Save(xmlWriter); } Thread.Sleep(_fileIoDelay); bool failed = true; Exception lastException = null; for (int i = 0; i < NumberOfRetries; i++) { DateTime lastSuccessfulFileChange = fileRecord.FileModificationDate; try { fileRecord.FileModificationDate = DateTime.MinValue; File.Copy(fileRecord.TempFilePath, fileRecord.FilePath, true); failed = false; break; } catch (Exception ex) { fileRecord.FileModificationDate = lastSuccessfulFileChange; lastException = ex; Thread.Sleep(10 * (i + 1)); } } if (!failed) { Thread.Sleep(_fileIoDelay); File.Delete(fileRecord.TempFilePath); } else { Log.LogCritical(LogTitle, "Failed deleting the file: " + fileRecord.FilePath); if (lastException != null) throw lastException; throw new InvalidOperationException("Failed to delete a file, this code shouldn't be reacheable"); } fileRecord.FileModificationDate = C1File.GetLastWriteTime(fileRecord.FilePath); } catch (Exception exception) { Log.LogCritical(LogTitle, "Failed to save data to the file file:" + fileRecord.FilePath); Log.LogCritical(LogTitle, exception); thrownException = exception; } } // ThreadAbortException should have a higher prioriry, and therefore we're doing rethrow in a separate block if (thrownException != null) throw thrownException; }
private static void DoSave(FileRecord fileRecord) { XDocument xDocument = new XDocument(); XElement root = new XElement(GetRootElementName(fileRecord.ElementName)); xDocument.Add(root); var recordSet = fileRecord.RecordSet; List <XElement> elements = new List <XElement>(recordSet.Index.GetValues()); string key = fileRecord.FilePath.ToLowerInvariant(); Func <IEnumerable <XElement>, IOrderedEnumerable <XElement> > orderer; if (TryGetFileOrderer(out orderer, fileRecord.FilePath)) { var orderedElements = orderer(elements); orderedElements.ForEach(root.Add); } else { elements.ForEach(root.Add); } Exception thrownException = null; // Writing the file in the "catch" block in order to prevent chance of corrupting the file by experiencing ThreadAbortException. try { } finally { try { // Saving to temp file and file move to prevent broken saves XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.CheckCharacters = false; xmlWriterSettings.Indent = true; using (XmlWriter xmlWriter = XmlWriter.Create(fileRecord.TempFilePath, xmlWriterSettings)) { xDocument.Save(xmlWriter); } Thread.Sleep(_fileIoDelay); bool failed = true; Exception lastException = null; for (int i = 0; i < NumberOfRetries; i++) { DateTime lastSuccessfulFileChange = fileRecord.FileModificationDate; try { fileRecord.FileModificationDate = DateTime.MinValue; File.Copy(fileRecord.TempFilePath, fileRecord.FilePath, true); failed = false; break; } catch (Exception ex) { fileRecord.FileModificationDate = lastSuccessfulFileChange; lastException = ex; Thread.Sleep(10 * (i + 1)); } } if (!failed) { Thread.Sleep(_fileIoDelay); File.Delete(fileRecord.TempFilePath); } else { Log.LogCritical(LogTitle, "Failed deleting the file: " + fileRecord.FilePath); if (lastException != null) { throw lastException; } throw new InvalidOperationException("Failed to delete a file, this code shouldn't be reacheable"); } fileRecord.FileModificationDate = C1File.GetLastWriteTime(fileRecord.FilePath); } catch (Exception exception) { Log.LogCritical(LogTitle, "Failed to save data to the file file:" + fileRecord.FilePath); Log.LogCritical(LogTitle, exception); thrownException = exception; } } // ThreadAbortException should have a higher prioriry, and therefore we're doing rethrow in a separate block if (thrownException != null) { throw thrownException; } }
internal static void Save(FileRecord fileRecord) { _dirtyRecords.Enqueue(fileRecord); if (forceImmediateWrite) { Flush(); } }