public IEnumerable <IStreamPartition> Generate(Stream stream) { while (true) { byte[] buffer = new byte[PartitionSize]; var count = stream.Read(buffer, 0, buffer.Length); if (count <= 0) { break; } if (count < buffer.Length) { Array.Resize(ref buffer, count); } var path = TempProcessFiles.NewProcessFilePath(); File.WriteAllBytes(path, buffer); var partition = new FilePartition(path, buffer.LongLength); yield return(partition); } }
public IAsyncEnumerable <IStreamPartition> GenerateAsync(Stream stream, CancellationToken cancellationToken) { var helper = new AsyncEnumerableHelper <IStreamPartition>(); var arr = new byte[PartitionSize]; Action <byte[], int, int, CancellationToken> copier = (buffer, offset, count, CancellationToken) => { if (offset < 0) { return; } if (count <= 0) { return; } var end = offset + count; while (offset < end) { //todo: convert this to a Func<.., Task> so we can do the async without blocking. var take = Math.Min(PartitionSize, end - offset); if (arr.Length < take) { Array.Resize(ref arr, take); } else if (arr.Length > take) { arr = new byte[take]; } Buffer.BlockCopy(buffer, offset, arr, 0, take); var path = TempProcessFiles.NewProcessFilePath(); File.WriteAllBytes(path, arr); var partition = new FilePartition(path, arr.LongLength); helper.SetNext(partition); offset += take; } }; var cache = new StreamWriter( (data, offset, count) => { Console.WriteLine($"Received partition of size {data.Length} with offset {offset} and count {count}"); copier(data, offset, count, CancellationToken.None); }, (data, offset, count, ct) => { Console.WriteLine($"Received ASYNC partition of size {data.Length} with offset {offset} and count {count}"); copier(data, offset, count, ct); return(Task.CompletedTask); }, totalSize => { Console.WriteLine("Received total length"); }); var task = stream .CopyToAsync(cache, PartitionSize, cancellationToken) .ContinueWith(done => { Console.WriteLine("Copy To is DONE"); helper.MarkComplete(); }); return(helper.GetEnumerable()); }