void ISnapshotStorage.Init() { if (!Directory.Exists(_path)) { Directory.CreateDirectory(_path); } var fileName = Path.Combine(_path, _serializer.FileName); byte[] buffer; Version version; if (File.Exists(fileName)) { using (var stream = File.OpenRead(fileName)) { version = new Version(stream.ReadByte(), stream.ReadByte()); buffer = new byte[_serializer.GetSnapshotSize(version)]; while (stream.Position < stream.Length) { stream.ReadBytes(buffer, buffer.Length); var message = _serializer.Deserialize(version, buffer); _snapshots.Add(_serializer.GetSecurityId(message), Tuple.Create(stream.Position - buffer.Length, message)); } _maxOffset = stream.Position; } } else { version = _serializer.Version; _maxOffset = 2; // version bytes buffer = new byte[_serializer.GetSnapshotSize(version)]; } _snapshotSize = buffer.Length; var isFlushing = false; ThreadingHelper.Timer(() => { Tuple <long, TMessage>[] changed; lock (_snapshots.SyncRoot) { if (_dirtySecurities.Count == 0) { return; } if (isFlushing) { return; } isFlushing = true; changed = _dirtySecurities.Select(id => { var tuple = _snapshots[id]; return(Tuple.Create(tuple.Item1, (TMessage)tuple.Item2.Clone())); }).OrderBy(t => t.Item1).ToArray(); _dirtySecurities.Count = 0; } try { using (var stream = File.OpenWrite(fileName)) { if (stream.Length == 0) { stream.WriteByte((byte)version.Major); stream.WriteByte((byte)version.Minor); } foreach (var tuple in changed) { stream.Seek(tuple.Item1, SeekOrigin.Begin); Array.Clear(buffer, 0, buffer.Length); _serializer.Serialize(version, tuple.Item2, buffer); stream.Write(buffer, 0, buffer.Length); } } } catch (Exception ex) { ex.LogError(); } lock (_snapshots.SyncRoot) isFlushing = false; }).Interval(TimeSpan.FromSeconds(10)); }