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.