I'm revising the code and notice that I get a suggestion to use the extension method AsMemory(...). I've never seen it before nor ha a reason to consider it. Never the less, one's either learn och obsoletes, so I got intrigued.
After reading the (rather limited) docs and (equally poor) set of blogs (honestly, this one) was the only remotely relevant I found, I decided I'm too ignorant to make a judgement call on this.
This is a sample of the code used.
await using FileStream input = new(path, FileMode.Open);
byte[] buffer = new byte[1024];
long remaining = input.Length;
int index = 0;
do
{
  int read = await input.ReadAsync(buffer, 0, Config.Chunk);
  remaining -= read;
  await using FileStream output = new(destination, FileMode.CreateNew);
  await output.WriteAsync(buffer, 0, read);
} while (remaining > 0);
input.Close();
What's the practical difference between those two readings from a stream? Where can I find more relevant and reliable information?
int read1 = await input.ReadAsync(buffer, 0, Config.Chunk);
int read2 = await input.ReadAsync(buffer.AsMemory(0, Config.Chunk));
I strongly hope that it has to do with performance optimization and/or thread management. However, I also hope to be handsome and funny, which was a mistake...
The same question goes for the writing operation, I guess.
await output.WriteAsync(buffer, 0, read);
await output.WriteAsync(buffer.AsMemory(0, read));
None, in this case.
The overload does exactly the same thing as your own code: it creates a ReadOnlyMemory from the buffer array.
Source code is here: (it eventually reaches a class called FileStreamStrategy)
public sealed override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
    WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask();
public sealed override ValueTask WriteAsync(ReadOnlyMemory<byte> source, CancellationToken cancellationToken)
{
    long writeOffset = CanSeek ? Interlocked.Add(ref _filePosition, source.Length) - source.Length : -1;
    return RandomAccess.WriteAtOffsetAsync(_fileHandle, source, writeOffset, cancellationToken, this);
}
Having said that, in many cases it is useful. This is normally where you would get a Memory from somewhere else, for example from an unmanaged memory block, or from some kind of array pool.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With