private async Task <ReadFileResult> ReadFile(int length) { IBuffer content = bufferAllocator.Allocate(length); Stream dest = content.GetStream(); IMD5HashProvider chunkHash = MD5HashProviderFactory.GetHashProvider().CreateHash(); byte[] b = ArrayPool <byte> .Shared.Rent(Configuration.BufferSize); try { int read = 0; int toRead = length; do { read = await fileStream.ReadAsync(b, offset : 0, count : Math.Min(b.Length, toRead)).ConfigureAwait(false); toRead -= read; await dest.WriteAsync(b, offset : 0, count : read).ConfigureAwait(false); chunkHash.Append(b, offset: 0, size: read); fileHash.Append(b, offset: 0, size: read); } while (read > 0 && toRead > 0); if (toRead > 0) { throw new Exception($"Expected to read {length} bytes, actual read {length - toRead} bytes"); } chunkHash.Finalize(ArrayPool <byte> .Shared.Rent(0), 0, 0); return(new ReadFileResult { Content = content, Hash = chunkHash.GetComputedHashAsString() }); } catch { content.Dispose(); throw; } finally { ArrayPool <byte> .Shared.Return(b); dest.Dispose(); } }