Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
| Vlastnost | Hodnota |
|---|---|
| ID pravidla | CA1844 |
| Název | Poskytnutí přepisů asynchronních metod založených na paměti při podtřídě Stream |
| Kategorie | Výkon |
| Oprava způsobující chybu nebo chybu způsobující chybu | Nenarušující |
| Povoleno ve výchozím nastavení v .NET 10 | Jako návrh |
Příčina
Typ odvozený z Stream přepsání ReadAsync(Byte[], Int32, Int32, CancellationToken) , ale nepřepíše ReadAsync(Memory<Byte>, CancellationToken). Nebo typ odvozený z Stream přepsání WriteAsync(Byte[], Int32, Int32, CancellationToken) , ale nepřepíše WriteAsync(ReadOnlyMemory<Byte>, CancellationToken).
Popis pravidla
Byly přidány metody založené na ReadAsyncWriteAsync paměti, aby se zlepšil výkon, který se dosahuje několika způsoby:
-
ValueTaskVrátí místoValueTask<int>Taska místo aTask<int>v uvedeném pořadí. - Umožňují předání libovolného typu vyrovnávací paměti, aniž by musely provádět další kopii do pole.
Aby bylo možné tyto výhody výkonu realizovat, musí typy odvozené z Stream nich poskytovat vlastní implementaci založenou na paměti. Jinak bude výchozí implementace nucena zkopírovat paměť do pole, aby volala implementaci založenou na poli, což vede ke snížení výkonu. Když volající předá v Memory<T> instanci nebo ReadOnlyMemory<T> instanci, která není maticí, bude mít vliv na výkon více.
Jak opravit porušení
Nejjednodušší způsob, jak opravit porušení, je přepsat implementaci založenou na poli jako implementaci založenou na paměti a pak implementovat metody založené na polích z hlediska metod založených na paměti.
Example
// This class violates the rule.
public class BadStream : Stream
{
private readonly Stream _innerStream;
public BadStream(Stream innerStream)
{
_innerStream = innerStream;
}
public override bool CanRead => _innerStream.CanRead;
public override bool CanSeek => _innerStream.CanSeek;
public override bool CanWrite => _innerStream.CanWrite;
public override long Length => _innerStream.Length;
public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; }
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
// ...
return await _innerStream.ReadAsync(buffer, offset, count, cancellationToken);
}
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
// ...
await _innerStream.WriteAsync(buffer, offset, count, cancellationToken);
}
// Other required overrides
public override void Flush() => _innerStream.Flush();
public override int Read(byte[] buffer, int offset, int count) => _innerStream.Read(buffer, offset, count);
public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin);
public override void SetLength(long value) => _innerStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count);
}
// This class satisfies the rule.
public class GoodStream : Stream
{
private readonly Stream _innerStream;
public GoodStream(Stream innerStream)
{
_innerStream = innerStream;
}
public override bool CanRead => _innerStream.CanRead;
public override bool CanSeek => _innerStream.CanSeek;
public override bool CanWrite => _innerStream.CanWrite;
public override long Length => _innerStream.Length;
public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; }
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
{
// ...
return await _innerStream.ReadAsync(buffer, cancellationToken);
}
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
// ...
await _innerStream.WriteAsync(buffer, cancellationToken);
}
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return await this.ReadAsync(buffer.AsMemory(offset, count), cancellationToken);
}
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
await this.WriteAsync(buffer.AsMemory(offset, count), cancellationToken);
}
// Other required overrides
public override void Flush() => _innerStream.Flush();
public override int Read(byte[] buffer, int offset, int count) => _innerStream.Read(buffer, offset, count);
public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin);
public override void SetLength(long value) => _innerStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count);
}
Kdy potlačit upozornění
Pokud platí některá z následujících situací, je bezpečné potlačit upozornění z tohoto pravidla:
- Dosažení výkonu není problém.
- Víte, že vaše
Streampodtřída bude používat pouze metody založené na polích. - Vaše
Streampodtřída obsahuje závislosti, které nepodporují vyrovnávací paměti.
Potlačení upozornění
Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.
#pragma warning disable CA1844
// The code that's violating the rule is on this line.
#pragma warning restore CA1844
Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.
[*.{cs,vb}]
dotnet_diagnostic.CA1844.severity = none
Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.