protected void SaveMobiles(SaveMetrics metrics) { Dictionary <Serial, Mobile> mobiles = World.Mobiles; GenericWriter idx; GenericWriter tdb; GenericWriter bin; if (UseSequentialWriters) { idx = new BinaryFileWriter(World.MobileIndexPath, false); tdb = new BinaryFileWriter(World.MobileTypesPath, false); bin = new BinaryFileWriter(World.MobileDataPath, true); } else { idx = new AsyncWriter(World.MobileIndexPath, false); tdb = new AsyncWriter(World.MobileTypesPath, false); bin = new AsyncWriter(World.MobileDataPath, true); } idx.Write((int)mobiles.Count); foreach (Mobile m in mobiles.Values) { long start = bin.Position; idx.Write((int)m.m_TypeRef); idx.Write((int)m.Serial); idx.Write((long)start); m.Serialize(bin); if (metrics != null) { metrics.OnMobileSaved((int)(bin.Position - start)); } idx.Write((int)(bin.Position - start)); m.FreeCache(); } tdb.Write((int)World.m_MobileTypes.Count); for (int i = 0; i < World.m_MobileTypes.Count; ++i) { tdb.Write(World.m_MobileTypes[i].FullName); } idx.Close(); tdb.Close(); bin.Close(); }
private Task SaveMobiles() { //Start the blocking consumer; this runs in background. Task commitTask = StartCommitTask(_mobileThreadWriters, _mobileData, _mobileIndex); IEnumerable <Mobile> mobiles = World.Mobiles.Values; //Start the producer. Parallel.ForEach(mobiles, () => new QueuedMemoryWriter(), (Mobile mobile, ParallelLoopState state, QueuedMemoryWriter writer) => { long startPosition = writer.Position; mobile.Serialize(writer); int size = (int)(writer.Position - startPosition); writer.QueueForIndex(mobile, size); if (_metrics != null) { _metrics.OnMobileSaved(size); } return(writer); }, (writer) => { writer.Flush(); _mobileThreadWriters.Add(writer); }); _mobileThreadWriters.CompleteAdding(); //We only get here after the Parallel.ForEach completes. Lets our task tell the consumer that we're done return(commitTask); }