Provide memory-based overrides of async methods when subclassing 'Stream'
Provide memory-based overrides of async methods when subclassing 'Stream'
Microsoft docsDescription
The memory-based ReadAsync and WriteAsync methods were added to improve performance, which they accomplish in multiple ways:
- They return
ValueTaskandValueTask<int>instead ofTaskandTask<int>, respectively. - They allow any type of buffer to be passed in without having to perform an extra copy to an array.
In order to realize these performance benefits, types that derive from System.IO.Stream must provide their own memory-based implementation. Otherwise, the default implementation will be forced to copy the memory into an array in order to call the array-based implementation, resulting in reduced performance. When the caller passes in a System.Memory1 or System.ReadOnlyMemory1 instance that's not backed by an array, performance is affected more.
Cause
A type derived from System.IO.Stream overrides System.IO.Stream.ReadAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken) but does not override System.IO.Stream.ReadAsync(System.Memory{System.Byte},System.Threading.CancellationToken). Or, a type derived from System.IO.Stream overrides System.IO.Stream.WriteAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken) but does not override System.IO.Stream.WriteAsync(System.ReadOnlyMemory{System.Byte},System.Threading.CancellationToken).
How to fix violations
The easiest way to fix violations is to rewrite your array-based implementation as a memory-based implementation, and then implement the array-based methods in terms of the memory-based methods.
Example
#pragma warning disable CA1844
// The code that's violating the rule is on this line.
#pragma warning restore CA1844When to suppress
It's safe to suppress a warning from this rule if any of the following situations apply:
- The performance hit is not a concern.
- You know that your
Streamsubclass will only ever use the array-based methods. - Your
Streamsubclass has dependencies that don't support memory-based buffers.