Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
| Tulajdonság | Érték |
|---|---|
| Szabályazonosító | CA1844 |
| Cím | Az aszinkron metódusok memóriaalapú felülbírálásának biztosítása a Stream alosztályozása során |
| Kategória | Teljesítmény |
| A javítás kompatibilitástörő vagy nem törik | Nem törés |
| Alapértelmezés szerint engedélyezve a .NET 10-ben | Javaslatként |
Ok
Felülbírálásokból Stream származtatott, de nem felülbíráló ReadAsync(Byte[], Int32, Int32, CancellationToken)ReadAsync(Memory<Byte>, CancellationToken)típus. Vagy a felülbírálásokból Stream származtatott, de nem felülbíráló WriteAsync(Byte[], Int32, Int32, CancellationToken)WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)típus.
Szabály leírása
A memóriaalapú ReadAsync és WriteAsync metódusok a teljesítmény javítása érdekében lettek hozzáadva, amelyeket több módon is végrehajtanak:
-
ValueTaskVisszatérnek, ésValueTask<int>helyettükTaskésTask<int>helyettük. - Lehetővé teszik bármilyen típusú puffer átadását anélkül, hogy további másolatot kellene készítenie egy tömbre.
Ezeknek a teljesítménybeli előnyöknek a megvalósítása érdekében az abból Stream származó típusoknak saját memóriaalapú implementációt kell biztosítaniuk. Ellenkező esetben az alapértelmezett implementációnak egy tömbbe kell másolnia a memóriát, hogy meghívja a tömbalapú implementációt, ami alacsonyabb teljesítményt eredményez. Ha a hívó egy Memory<T> tömb által nem támogatott példányon vagy ReadOnlyMemory<T> példányon halad át, a teljesítményre nagyobb hatással van.
Szabálysértések kijavítása
A szabálysértések megoldásának legegyszerűbb módja a tömbalapú implementáció memóriaalapú implementációként történő újraírása, majd a tömbalapú metódusok implementálása a memóriaalapú metódusok szempontjából.
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);
}
Mikor kell letiltani a figyelmeztetéseket?
Az alábbi helyzetek bármelyike esetén nyugodtan letilthatja a szabály figyelmeztetését:
- A teljesítménybeli találat nem jelent problémát.
- Tudja, hogy az
Streamalosztály csak tömbalapú metódusokat fog használni. - Az
Streamalosztály olyan függőségekkel rendelkezik, amelyek nem támogatják a memóriaalapú puffereket.
Figyelmeztetés mellőzése
Ha csak egyetlen szabálysértést szeretne letiltani, adjon hozzá előfeldolgozási irányelveket a forrásfájlhoz a szabály letiltásához és újbóli engedélyezéséhez.
#pragma warning disable CA1844
// The code that's violating the rule is on this line.
#pragma warning restore CA1844
Ha le szeretné tiltani egy fájl, mappa vagy projekt szabályát, állítsa annak súlyosságát none a konfigurációs fájlban.
[*.{cs,vb}]
dotnet_diagnostic.CA1844.severity = none
További információ: Kódelemzési figyelmeztetések letiltása.