public void AddProfile(ExplorerTimeProfile profile) { timeProfiles.Enqueue(profile); while (timeProfiles.Count > MaxProfiles) timeProfiles.Dequeue(); }
public override bool SaveFiles() { bool success = false; var exFiles = new List<string>{ WorldFile, PlayerFile, WorldIDFile }; var backupFiles = exFiles.Select(x => x + ".bak").ToList(); Stopwatch totalTimer = new Stopwatch(); totalTimer.Start(); //First, set up the profiler and set the number of worlds to process ExplorerTimeProfile profile = new ExplorerTimeProfile(); profile.WorldProcesses += worlds.Count(x => x.CanPlay); try { //Now, simulate all worlds //Directory.CreateDirectory(Path.GetDirectoryName(DropboxPath + HelpFile)); Parallel.ForEach(worlds.Where(x => x.CanPlay), world => { Stopwatch simulateTimer = new Stopwatch(); simulateTimer.Start(); world.WorldData.Simulate(); simulateTimer.Stop(); lock (ProfileLocker) { profile.TotalWorldSimulationTime += simulateTimer.ElapsedMilliseconds; } }); //Next, start on the serialization Thread thread = new Thread(() => { Stopwatch fileTimer = new Stopwatch(); fileTimer.Start(); //Copy original files to backup files. try { for(int i = 0; i < exFiles.Count; i++) { if(File.Exists(exFiles[i])) File.Copy(exFiles[i], backupFiles[i], true); } //Now attempt to serialize everything. MySerialize2.SaveObject<List<WorldInstance>>(WorldFile, worlds); MySerialize2.SaveObject<Dictionary<int, ExplorerPlayer>>(PlayerFile, allPlayers); MySerialize2.SaveObject<int>(WorldIDFile, WorldInstance.nextWorldID); //After serializing, MAKE SURE WE CAN STILL LOAD IT~! var tempworlds = MySerialize2.LoadObject<List<WorldInstance>>(WorldFile); var tempallPlayers = MySerialize2.LoadObject<Dictionary<int, ExplorerPlayer>>(PlayerFile); var tempWorldID = MySerialize2.LoadObject<int>(WorldIDFile); /*success = MySerialize.SaveObject<List<WorldInstance>>(WorldFile, worlds) && MySerialize.SaveObject<Dictionary<int, ExplorerPlayer>>(PlayerFile, allPlayers) && MySerialize.SaveObject<int>(WorldIDFile, WorldInstance.nextWorldID);*/ } catch(Exception ex) { try { //Restore the backups (since we're assuming those worked) for(int i = 0; i < backupFiles.Count; i++) { if(File.Exists(backupFiles[i])) File.Copy(backupFiles[i], exFiles[i], true); } } catch(Exception ex2) { //DO SOMETHING WITH THE EXCEPTION HERE! Console.WriteLine("EXTREME EXGAME ERROR! COULD NOT RESTORE BACKUPS AFTER FAILED WRITES!"); } success = false; } fileTimer.Stop(); lock (ProfileLocker) { profile.SerializationTime = fileTimer.ElapsedMilliseconds; } }); thread.Start(); Directory.CreateDirectory(GetOption<string>("mapFolder")); //While we're serializing, we can also produce the images Parallel.ForEach(worlds.Where(x => x.CanPlay), world => { Stopwatch imageTimer = new Stopwatch(); imageTimer.Start(); SaveWorldImage(world); imageTimer.Stop(); lock (ProfileLocker) { profile.TotalWorldImageTime += imageTimer.ElapsedMilliseconds; } }); //Now that we're done, we need to WAIT for the serialization to finish thread.Join(); } catch { return false; } //This'll hopefull fix glitches if (WorldInstance.nextWorldID == 0) WorldInstance.nextWorldID++; //Finalize the profile information totalTimer.Stop(); profile.TotalTime += totalTimer.ElapsedMilliseconds; //...And add it to the profile queue AddProfile(profile); return success; }