private static async Task <IResource[]> ExtractResourcesAsync(Dictionary <string, int> defs) { const string ItemManager = DecompLocation + "scripts/items/ItemManager.as"; Console.WriteLine($"Loading {nameof(ItemIdTable)}"); var itemIdTable = new ItemIdTable(defs); var disposableParsers = new List <IDisposable>(1); Console.WriteLine("Discovering parsers..."); var parsers = Assembly .GetExecutingAssembly() .GetTypes() .Where(x => !x.IsInterface && x.GetInterfaces().Contains(typeof(IParser))) .Select(x => { var parser = (IParser)InjectionUtils.CreateNew(x, itemIdTable); if (x.GetInterfaces().Contains(typeof(IDisposable))) { disposableParsers.Add((IDisposable)parser); } return(parser); }) .ToArray(); Console.WriteLine($"{parsers.Length} Parsers discovered"); Console.WriteLine("Running Parser"); var results = new List <Task <IResource> >(); using (var fs = File.OpenRead(ItemManager)) using (var sr = new StreamReader(fs)) while (!sr.EndOfStream) { var rawLn = sr.ReadLine().Trim(); foreach (var i in parsers) { if (i.CanParse(rawLn)) { Console.WriteLine($"{i.GetType()} Parsing {rawLn}"); results.Add(i.ParseAsync(rawLn)); break; } } Console.WriteLine($"No parser found for {rawLn}"); } foreach (var i in disposableParsers) { Console.WriteLine($"Disposing {i}"); i.Dispose(); } return((await Task.WhenAll(results)) .Where(x => !(x is null)) .ToArray()); }