CA1835: Liever overbelasting op basis van geheugen van ReadAsync-/WriteAsync-methoden in streamklassen
Eigenschappen | Weergegeven als |
---|---|
Typenaam | PreferStreamAsyncMemoryOverloads |
Regel-id | CA1835 |
Titel | Liever overbelasting op basis van geheugen van ReadAsync/WriteAsync-methoden in streamklassen |
Categorie | Prestaties |
Oplossing is brekend of niet-brekend | Niet-brekend |
Standaard ingeschakeld in .NET 9 | Als suggestie |
Oorzaak
Met deze regel worden wachtende aanroepen van de op bytematrix gebaseerde methodeoverbelastingen gevonden ReadAsync
en WriteAsync
wordt voorgesteld om in plaats daarvan de overbelasting van de methode op basis van geheugen te gebruiken, omdat ze efficiënter zijn.
Beschrijving van regel
De overbelasting van de methode op basis van geheugen heeft een efficiënter geheugengebruik dan de bytematrix.
De regel werkt aan ReadAsync
en WriteAsync
aanroepen van elke klasse die overkomt van Stream.
De regel werkt alleen wanneer de methode wordt voorafgegaan door het await
trefwoord.
Gedetecteerde methode | Voorgestelde methode |
---|---|
ReadAsync(Byte[], Int32, Int32, CancellationToken) | ReadAsync(Memory<Byte>, CancellationToken) |
ReadAsync(Byte[], Int32, Int32) | ReadAsync(Memory<Byte>, CancellationToken) met CancellationToken ingesteld op default in C# of Nothing in Visual Basic. |
WriteAsync(Byte[], Int32, Int32, CancellationToken) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) |
WriteAsync(Byte[], Int32, Int32) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) met CancellationToken ingesteld op default in C# of Nothing in Visual Basic. |
Belangrijk
Zorg ervoor dat u de offset
argumenten en count
gehele getallen doorgeeft aan de gemaakte Memory
of ReadOnlyMemory
exemplaren.
Notitie
Regel CA1835 is beschikbaar in alle .NET-versies waar de overbelasting op basis van geheugen beschikbaar is:
- .NET Standard 2.1 en hoger.
- .NET Core 2.1 en hoger.
Schendingen oplossen
U kunt ze handmatig herstellen of u kunt ervoor kiezen om Visual Studio dit voor u te laten doen door de muisaanwijzer op de gloeilamp te bewegen die naast de methodeaanroep wordt weergegeven en de voorgestelde wijziging te selecteren. Voorbeeld:
De regel kan verschillende schendingen voor de ReadAsync
en WriteAsync
methoden detecteren. Hier volgen enkele voorbeelden van de gevallen die door de regel kunnen worden gedetecteerd:
Voorbeeld 1
Aanroepen van ReadAsync
, zonder en met een CancellationToken
argument:
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);
}
}
}
Oplossing:
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);
}
}
}
Voorbeeld 2
Aanroepen van WriteAsync
, zonder en met een CancellationToken
argument:
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);
}
}
}
Oplossing:
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);
}
}
}
Voorbeeld 3
Aanroepen met 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);
}
}
}
Oplossing:
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);
}
}
}
Niet-schendingen
Hieronder volgen enkele voorbeelden van aanroepen waarbij de regel niet wordt geactiveerd.
De retourwaarde wordt opgeslagen in een Task
variabele in plaats van te wachten:
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);
}
}
}
De retourwaarde wordt geretourneerd door de wrapping-methode in plaats van te wachten:
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);
}
}
De retourwaarde wordt gebruikt om aan te roepen ContinueWith
. Dit is de methode die wordt verwacht:
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 => { /* ... */ });
}
}
}
Wanneer waarschuwingen onderdrukken
Het is veilig om een schending van deze regel te onderdrukken als u zich geen zorgen maakt over het verbeteren van de prestaties bij het lezen of schrijven van buffers in streamklassen.
Een waarschuwing onderdrukken
Als u slechts één schending wilt onderdrukken, voegt u preprocessorrichtlijnen toe aan uw bronbestand om de regel uit te schakelen en vervolgens opnieuw in te schakelen.
#pragma warning disable CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835
Als u de regel voor een bestand, map of project wilt uitschakelen, stelt u de ernst none
ervan in op het configuratiebestand.
[*.{cs,vb}]
dotnet_diagnostic.CA1835.severity = none
Zie Codeanalysewaarschuwingen onderdrukken voor meer informatie.