using System; using System.IO; using System.Threading; using JD.Kernel.Classes; using JD.Kernel.StaticHelpers; using JD.Serializers.Xml; namespace JD.PropertyService { /// /// Properties that load/save automatically to/from a file. /// internal class AutoSavingProperties : PropertiesWrapper, IDisposable { #region Variables private static readonly TimeSpan AutoSavePeriod = TimeSpan.FromMinutes(5); private readonly string m_filename; private readonly Timer m_saveTimer; private bool m_isDirty; private readonly object m_saveLock = new object(); #endregion #region Constructor /// /// Constructor. /// public AutoSavingProperties(string filename, IProperties wrappedProperties) : base(wrappedProperties) { Throw.IfEmpty(filename, "filename"); Throw.IfNull(wrappedProperties, "wrappedProperties"); m_filename = filename; string directory = Path.GetDirectoryName(m_filename); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } if (File.Exists(m_filename)) { try { using (XmlSerializerReader reader = new XmlSerializerReader(File.OpenRead(filename))) { Wrapped.ReadFromXml(reader); } } catch { Clear(); } } wrappedProperties.PropertyChanged += wrappedProperties_PropertyChanged; m_saveTimer = new Timer(TimerCallback, null, AutoSavePeriod, AutoSavePeriod); } public void Dispose() { Wrapped.PropertyChanged -= wrappedProperties_PropertyChanged; DisposableHelper.SafeDispose(m_saveTimer); // Save it Save(); } #endregion #region Methods /// /// Saves the properties to disk. /// public override bool Save() { if (m_isDirty) { lock (m_saveLock) { if (m_isDirty) { try { using (var stream = System.IO.File.OpenWrite(m_filename)) { using (XmlSerializerWriter writer = new XmlSerializerWriter(stream)) { m_isDirty = false; Wrapped.WriteToXml(writer); } } } catch (Exception) { return false; } } } } return true; } #endregion #region Event Handlers private void TimerCallback(object arg) { Save(); } void wrappedProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) { m_isDirty = true; } #endregion } }