Share via


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 WriteAsyncwordt 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:

Codefix voor CA1835 - Liever overbelasting op basis van geheugen van ReadAsync-/WriteAsync-methoden in streamklassen

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.

Zie ook