private Task <ShapefileRecordInfoCollection> BuildShapeIndexData(IRandomAccessStream stream, CancellationTokenSource cancellationTokenSource) { var token = cancellationTokenSource.Token; var task = Task.Factory.StartNew( async() => { if (cancellationTokenSource.IsCancellationRequested) { return(null); } using (var shapeStream = stream.CloneStream()) { int offset = 36; shapeStream.Seek((ulong)offset); byte[] boundingBox = new byte[32]; await shapeStream.ReadAsync(boundingBox.AsBuffer(), 32u, InputStreamOptions.Partial); var recordInfos = new ShapefileRecordInfoCollection(); recordInfos.BoundingRect = GetBoundingRect(boundingBox, this.CoordinateValueConverter); offset = 100; shapeStream.Seek((ulong)offset); while (shapeStream.Position < shapeStream.Size) { if (cancellationTokenSource.IsCancellationRequested) { return(null); } byte[] recordHeader = new byte[8]; await shapeStream.ReadAsync(recordHeader.AsBuffer(), 8u, InputStreamOptions.Partial); // The content length for a record is the length of the record contents section measured in 16-bit words. int contentLength = ToInt32BigEndian(recordHeader, 4) * 2; offset += 8; recordInfos.Add(new ShapefileRecordInfo() { ContentOffset = offset, ContentLength = contentLength }); offset += contentLength; shapeStream.Seek((ulong)offset); } return(recordInfos); } }, token).Unwrap(); return(task); }
private MapShapeModelCollection ProcessItems(IRandomAccessStream shapeStream, ShapefileRecordInfoCollection recordInfos, CancellationTokenSource cancellationTokenSource) { if (cancellationTokenSource.IsCancellationRequested) { return(null); } int itemCount = recordInfos.Count; int maxDegreeOfParallelism = Environment.ProcessorCount; if (itemCount < maxDegreeOfParallelism) { maxDegreeOfParallelism = itemCount; } int remainder = itemCount % maxDegreeOfParallelism; int multiplier = (itemCount / maxDegreeOfParallelism) + (remainder > 0 ? 1 : 0); var token = cancellationTokenSource.Token; List <Task <MapShapeModelCollection> > tasks = new List <Task <MapShapeModelCollection> >(); for (int i = 0; i < maxDegreeOfParallelism; i++) { int start = i * multiplier; int end = Math.Min((i + 1) * multiplier, itemCount); ParseShapeTaskState taskState = new ParseShapeTaskState() { Start = start, End = end, Records = recordInfos, Stream = shapeStream, CancellationTokenSource = cancellationTokenSource, CoordinateConverter = this.CoordinateValueConverter }; var task = Task.Factory.StartNew <Task <MapShapeModelCollection> >(ParseShapes, taskState, token, TaskCreationOptions.AttachedToParent, TaskScheduler.Current).Unwrap(); tasks.Add(task); } Task.WaitAll(tasks.ToArray()); MapShapeModelCollection models = tasks[0].Result; for (int i = 1; i < maxDegreeOfParallelism; i++) { var modelsToMerge = tasks[i].Result; if (modelsToMerge == null) { continue; } foreach (var model in modelsToMerge) { models.Add(model); } } models.BoundingRect = recordInfos.BoundingRect; return(models); }