public static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Usage: ParseTsgReplays.exe path-to-replays [-rebuild [-unfinished]]"); return; } var rebuildBase = false; if (args.Contains("-rebuild", StringComparer.OrdinalIgnoreCase)) { rebuildBase = true; } var unfinished = false; if (args.Contains("-unfinished", StringComparer.OrdinalIgnoreCase)) { unfinished = true; } using (var db = new ReplaysContext()) { db.Database.Migrate(); if (!rebuildBase) { var allReplays = db.Replays.AsQueryable(); if (unfinished) { allReplays = allReplays.Where(r => r.IsFinished == true); } ExistingRecords = allReplays.Select(r => new ReplayKey(r.Server, r.Timestamp)).ToHashSet(); } }; var task = Task.Run(async() => { var set = new HashSet <ReplayKey>(); var counter = 0; List <Replay> toAdd = new List <Replay>(); await foreach (var r in queue.Reader.ReadAllAsync()) { if (ExistingRecords.Add(new(r.Server, r.Timestamp))) { toAdd.Add(r); if (++counter % 1000 == 0) { using (var db = new ReplaysContext()) { db.Replays.AddRange(toAdd); await db.SaveChangesAsync(); counter = 0; toAdd.Clear(); } } } } using (var db = new ReplaysContext()) { db.Replays.AddRange(toAdd); await db.SaveChangesAsync(); } }); var provider = CultureInfo.InvariantCulture; Task.Run(async() => { await foreach (var t in exceptions.Reader.ReadAllAsync()) { Console.WriteLine(t.Item1); Console.WriteLine(t.Item2.ToString()); Console.WriteLine(); } }); var dir = args[0]; if (Path.HasExtension(dir)) { if (Path.GetExtension(dir) == ".pbo") { ParsePbo(dir); } if (Path.GetExtension(dir) == ".7z") { ParseArchive(dir); } } else { Parallel.ForEach(Directory.EnumerateFiles(dir, "*.pbo", SearchOption.AllDirectories), ParsePbo); Parallel.ForEach(Directory.EnumerateFiles(dir, "*.7z", SearchOption.AllDirectories), ParseArchive); } Console.WriteLine("Processed {0} parsed {1}", counterProcessed, counterParsed); queue.Writer.TryComplete(); exceptions.Writer.TryComplete(); task.Wait(); //ClearDuplicates(); }