Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
| Właściwości | Wartość |
|---|---|
| Nazwa typu | PreferStreamAsyncMemoryOverloads |
| Identyfikator reguły | CA1835 |
| Tytuł | Preferuj przeciążenia oparte na pamięci metod ReadAsync/WriteAsync w klasach opartych na strumieniu |
| Kategoria | Wydajność |
| Poprawka łamiąca lub nienaruszająca | Niezgodność |
| Domyślnie włączone na platformie .NET 10 | Jako sugestia |
| Zastosowane języki | C# i Visual Basic |
Przyczyna
Ta reguła lokalizuje oczekiwane wywołania przeciążeń metody, które wykorzystują tablicę bajtów, dla ReadAsync i WriteAsync, i sugeruje użycie przeciążeń metody opartych na pamięci, ponieważ są one bardziej wydajne.
Opis reguły
Przeciążenia metody opartej na pamięci mają bardziej wydajne użycie pamięci niż te oparte na tablicy bajtów.
Reguła działa na ReadAsync i WriteAsync wywołaniach dowolnej klasy dziedziczącej z Stream.
Reguła działa tylko wtedy, gdy metoda jest poprzedzona await słowem kluczowym.
| Wykryta metoda | Sugerowana metoda |
|---|---|
| ReadAsync(Byte[], Int32, Int32, CancellationToken) | ReadAsync(Memory<Byte>, CancellationToken) |
| ReadAsync(Byte[], Int32, Int32) |
ReadAsync(Memory<Byte>, CancellationToken) z ustawioną wartością CancellationTokendefault w języku C#lub Nothing w Visual Basic. |
| WriteAsync(Byte[], Int32, Int32, CancellationToken) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) |
| WriteAsync(Byte[], Int32, Int32) |
WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) z CancellationToken ustawionym na default w języku C# lub Nothing w Visual Basic. |
Ważne
Pamiętaj, aby przekazać offset argumenty i count liczby całkowite do utworzonych Memory wystąpień lub ReadOnlyMemory .
Uwaga
Reguła CA1835 jest dostępna we wszystkich wersjach platformy .NET, w których dostępne są przeciążenia oparte na pamięci:
- .NET Standard 2.1 lub nowszy.
- .NET Core 2.1 lub nowszy.
Jak naprawić naruszenia
Możesz je naprawić ręcznie, lub możesz pozwolić programowi Visual Studio to zrobić za Ciebie, umieszczając wskaźnik myszy na żarówce, która jest wyświetlana obok wywołania metody, i wybrać sugerowaną zmianę. Przykład:
Reguła może wykrywać różne naruszenia metod ReadAsync i WriteAsync . Oto przykłady przypadków, w których reguła może wykryć:
Przykład 1
Wywołania ReadAsync bez argumentu i wywołania z 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);
}
}
}
Naprawa:
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);
}
}
}
Przykład 2
Wywołania WriteAsync, bez argumentu oraz z 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);
}
}
}
Naprawa:
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);
}
}
}
Przykład 3
Wywołania przy użyciu 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);
}
}
}
Naprawa:
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);
}
}
}
Brak naruszeń
Poniżej przedstawiono kilka przykładów wywołań, w których reguła nie będzie wyzwolona.
Wartość zwracana jest zapisywana w zmiennej Task , a nie oczekiwana:
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);
}
}
}
Zwracana wartość jest zwracana przez metodę opakowującą zamiast być oczekiwaną.
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);
}
}
Wartość zwracana jest używana do wywołania metody ContinueWith, która jest oczekiwana.
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 => { /* ... */ });
}
}
}
Kiedy pomijać ostrzeżenia
Można bezpiecznie pominąć naruszenie tej reguły, jeśli nie martwisz się o poprawę wydajności podczas odczytywania lub zapisywania buforów w klasach strumieniowych.
Pomijanie ostrzeżenia
Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.
#pragma warning disable CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835
Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.
[*.{cs,vb}]
dotnet_diagnostic.CA1835.severity = none
Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.