CA1835: Upřednostněte přetížení na základě paměti metod ReadAsync/WriteAsync v datových třídách
Vlastnost | Hodnota |
---|---|
Název typu | PreferStreamAsyncMemoryOverloads |
ID pravidla | CA1835 |
Název | Upřednostněte přetížení metod ReadAsync/WriteAsync v datových třídách. |
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 9 | Jako návrh |
Příčina
Toto pravidlo vyhledá očekávané vyvolání přetížení metody založené na bajtech pole a ReadAsync
WriteAsync
navrhuje použití přetížení metody založené na paměti místo toho, protože jsou efektivnější.
Popis pravidla
Přetížení metody založené na paměti mají efektivnější využití paměti než bajtové pole.
Pravidlo funguje na ReadAsync
a WriteAsync
vyvolání jakékoli třídy, která dědí z Stream.
Pravidlo funguje pouze v případech, kdy je před metodou await
klíčové slovo.
Zjištěná metoda | Navrhovaná metoda |
---|---|
ReadAsync(Byte[], Int32, Int32, CancellationToken) | ReadAsync(Memory<Byte>, CancellationToken) |
ReadAsync(Byte[], Int32, Int32) | ReadAsync(Memory<Byte>, CancellationToken)default v CancellationToken jazyce C# nebo Nothing v jazyce Visual Basic. |
WriteAsync(Byte[], Int32, Int32, CancellationToken) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) |
WriteAsync(Byte[], Int32, Int32) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)default v CancellationToken jazyce C# nebo Nothing v jazyce Visual Basic. |
Důležité
Nezapomeňte do vytvořených Memory
nebo ReadOnlyMemory
instancí předat offset
count
celočíselné argumenty.
Poznámka:
Pravidlo CA1835 je k dispozici ve všech verzích .NET, kde jsou k dispozici přetížení založená na paměti:
- .NET Standard 2.1 a novější.
- .NET Core 2.1 a novější.
Jak opravit porušení
Můžete je opravit ručně, nebo se můžete rozhodnout, že to visual Studio udělá za vás, když najedete myší na žárovku, která se zobrazí vedle vyvolání metody, a výběrem navrhované změny. Příklad:
Toto pravidlo může detekovat různá porušení pravidel ReadAsync
a WriteAsync
metod. Tady jsou příklady případů, které pravidlo dokáže rozpoznat:
Příklad 1
Vyvolání ReadAsync
funkce , bez a s argumentem CancellationToken
:
using System;
using System.IO;
using System.Threading;
class MyClass
{
public async void MyMethod(CancellationToken ct)
{
using (FileStream s = new FileStream("path.txt", FileMode.Create))
{
byte[] buffer = new byte[s.Length];
await s.ReadAsync(buffer, 0, buffer.Length);
await s.ReadAsync(buffer, 0, buffer.Length, ct);
}
}
}
Opravit:
using System;
using System.IO;
using System.Threading;
class MyClass
{
public async void MyMethod(CancellationToken ct)
{
using (FileStream s = new FileStream("path.txt", FileMode.Create))
{
byte[] buffer = new byte[s.Length];
await s.ReadAsync(buffer.AsMemory(0, buffer.Length));
await s.ReadAsync(buffer.AsMemory(0, buffer.Length), ct);
}
}
}
Příklad 2
Vyvolání WriteAsync
funkce , bez a s argumentem CancellationToken
:
using System;
using System.IO;
using System.Threading;
class MyClass
{
public async void MyMethod(CancellationToken ct)
{
using (FileStream s = File.Open("path.txt", FileMode.Open))
{
byte[] buffer = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 };
await s.WriteAsync(buffer, 0, buffer.Length);
await s.WriteAsync(buffer, 0, buffer.Length, ct);
}
}
}
Opravit:
using System;
using System.IO;
using System.Threading;
class MyClass
{
public async void MyMethod()
{
using (FileStream s = File.Open("path.txt", FileMode.Open))
{
byte[] buffer = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 };
await s.WriteAsync(buffer.AsMemory(0, buffer.Length));
await s.WriteAsync(buffer.AsMemory(0, buffer.Length), ct);
}
}
}
Příklad 3
Vyvolání s ConfigureAwait
:
using System;
using System.IO;
using System.Threading;
class MyClass
{
public async void MyMethod()
{
using (FileStream s = File.Open("path.txt", FileMode.Open))
{
byte[] buffer1 = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 };
await s.WriteAsync(buffer1, 0, buffer1.Length).ConfigureAwait(false);
byte[] buffer2 = new byte[s.Length];
await s.ReadAsync(buffer2, 0, buffer2.Length).ConfigureAwait(true);
}
}
}
Opravit:
using System;
using System.IO;
using System.Threading;
class MyClass
{
public async void MyMethod()
{
using (FileStream s = File.Open("path.txt", FileMode.Open))
{
byte[] buffer1 = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 };
await s.WriteAsync(buffer1.AsMemory(0, buffer1.Length)).ConfigureAwait(false);
byte[] buffer2 = new byte[s.Length];
await s.ReadAsync(buffer2.AsMemory(0, buffer.Length)).ConfigureAwait(true);
}
}
}
Neresektování
Následuje několik příkladů vyvolání, kdy se pravidlo neaktivuje .
Vrácená hodnota je uložena v Task
proměnné místo toho, aby byla očekávána:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
class MyClass
{
public void MyMethod()
{
byte[] buffer = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 };
using (FileStream s = new FileStream("path.txt", FileMode.Create))
{
Task t = s.WriteAsync(buffer, 0, buffer.Length);
}
}
}
Návratová hodnota je vrácena metodou wrapping namísto očekávání:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
class MyClass
{
public Task MyMethod(FileStream s, byte[] buffer)
{
return s.WriteAsync(buffer, 0, buffer.Length);
}
}
Návratová hodnota se používá k volání ContinueWith
, což je metoda, která se očekává:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
class MyClass
{
public void MyMethod()
{
byte[] buffer = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 };
using (FileStream s = new FileStream("path.txt", FileMode.Create))
{
await s.WriteAsync(buffer, 0, buffer.Length).ContinueWith(c => { /* ... */ });
}
}
}
Kdy potlačit upozornění
Je bezpečné potlačit porušení tohoto pravidla, pokud vás nezajímá zlepšení výkonu při čtení nebo zápisu vyrovnávacích pamětí ve třídách založených na datových proudech.
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 CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835
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.CA1835.severity = none
Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.