CA1835: Gebruik bij voorkeur de geheugen-gebaseerde overloads van de methoden ReadAsync en WriteAsync in stream-gebaseerde klassen.

Eigenschap Waarde
Typenaam PreferStreamAsyncMemoryOverloads
Regel-id CA1835
Titel Geef de voorkeur aan overloads die gebaseerd zijn op geheugen van de ReadAsync/WriteAsync-methoden in op streams gebaseerde klassen.
Categorie Prestaties
Fix kan brekend of niet-brekend zijn Niet-brekend
Standaard ingeschakeld in .NET 10 Als suggestie
Toepasselijke talen C# en Visual Basic

Oorzaak

Met deze regel worden verwachte aanroepen van de op byte-array gebaseerde methodeoverbelastingen voor ReadAsync en WriteAsync gevonden, en suggereert om in plaats daarvan de op geheugen gebaseerde methodeoverbelastingen te gebruiken, omdat deze efficiënter zijn.

Beschrijving van regel

Overloads van methoden op basis van geheugen hebben een efficiënter geheugengebruik dan die op basis van byte-arrays.

De regel werkt op ReadAsync en WriteAsync aanroepen van elke klasse die erft 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.

Hoe schendingen op te lossen

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:

Codefix voor CA1835 - De voorkeur geven aan geheugen-gebaseerde overloads van de ReadAsync/WriteAsync-methoden in streamgebaseerde klassen

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 op streams gebaseerde klassen.

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 voor meer informatie Hoe codeanalysewaarschuwingen te onderdrukken.

Zie ook