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);
        }