public object Read(Newtonsoft.Json.JsonReader reader) { if (reader.TokenType != Newtonsoft.Json.JsonToken.StartObject) throw new Exception(); int w = ReadIntProperty(reader, "Width"); int h = ReadIntProperty(reader, "Height"); int d = ReadIntProperty(reader, "Depth"); var grid = new TileData[d, h, w]; reader.Read(); if (reader.TokenType != Newtonsoft.Json.JsonToken.PropertyName || (string)reader.Value != "TileData") throw new Exception(); ReadAndValidate(reader, Newtonsoft.Json.JsonToken.StartArray); var queue = new BlockingCollection<Tuple<int, byte[]>>(); var readerTask = Task.Factory.StartNew(() => { for (int i = 0; i < d; ++i) { reader.Read(); int z = (int)(long)reader.Value; byte[] buf = reader.ReadAsBytes(); queue.Add(new Tuple<int, byte[]>(z, buf)); } queue.CompleteAdding(); }); Parallel.For(0, d, i => { var tuple = queue.Take(); int z = tuple.Item1; byte[] arr = tuple.Item2; using (var memStream = new MemoryStream(arr)) { using (var decompressStream = new DeflateStream(memStream, CompressionMode.Decompress)) using (var streamReader = new BinaryReader(decompressStream)) { for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) grid[z, y, x].Raw = streamReader.ReadUInt64(); } } }); readerTask.Wait(); ReadAndValidate(reader, Newtonsoft.Json.JsonToken.EndArray); ReadAndValidate(reader, Newtonsoft.Json.JsonToken.EndObject); return grid; }