CA1835: A ReadAsync/WriteAsync metódusok memóriaalapú túlterhelésének előnyben részesítése streamalapú osztályokban

Tulajdonság Érték
Típus neve STREAMAszinkronMemóriaTúlterheléseketRészesítsdElőnyben
Szabályazonosító CA1835
Cím A ReadAsync/WriteAsync metódusok memóriaalapú túlterhelésének előnyben részesítése streamalapú osztályokban
Kategória Teljesítmény
A javítás romboló vagy nem romboló Nem törhető
Alapértelmezés szerint engedélyezve a .NET 10-ben Javaslatként
Alkalmazandó nyelvek C# és Visual Basic

Ok

Ez a szabály megkeresi a bájttömbalapú metódus túlterheléseinek ReadAsync várt meghívásait, és WriteAsyncehelyett a memóriaalapú metódus túlterhelését javasolja, mert hatékonyabbak.

Szabály leírása

A memóriaalapú metódusok túlterhelése hatékonyabb memóriahasználatot eredményez, mint a bájttömbalapúak.

A szabály ReadAsync és WriteAsync meghívásokon működik minden olyan osztály esetében, amely a Stream osztályból örököl.

A szabály csak akkor működik, ha a metódust megelőzi a await kulcsszó.

Észlelt metódus Javasolt módszer
ReadAsync(Byte[], Int32, Int32, CancellationToken) ReadAsync(Memory<Byte>, CancellationToken)
ReadAsync(Byte[], Int32, Int32) ReadAsync(Memory<Byte>, CancellationToken) a CancellationToken úgy van beállítva, hogy default a C#, vagy Nothing a Visual Basic esetében.
WriteAsync(Byte[], Int32, Int32, CancellationToken) WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)
WriteAsync(Byte[], Int32, Int32) WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) a CancellationToken értékre van állítva C#-ban, vagy a default értékre van állítva a Visual Basic-benNothing.

Fontos

Ügyeljen arra, hogy a offset és count egész szám típusú argumentumokat átadja a létrehozott Memory vagy ReadOnlyMemory példányoknak.

Megjegyzés

A CA1835 szabály minden .NET-verzióban elérhető, ahol a memóriaalapú túlterhelések elérhetők:

  • .NET Standard 2.1 vagy újabb.
  • .NET Core 2.1 vagy újabb.

Szabálysértések kijavítása

Ezeket manuálisan is kijavíthatja, vagy engedélyezheti a Visual Studio számára, ha a metódushívás mellett megjelenő villanykörte fölé viszi az egérmutatót, és kiválasztja a javasolt módosítást. Példa:

A CA1835 kódjavítása – A ReadAsync/WriteAsync metódusok memóriaalapú túlterhelésének előnyben részesítése streamalapú osztályokban

A szabály képes észlelni számos szabálysértést a ReadAsync és WriteAsync metódusok esetében. Íme néhány példa azokra az esetekre, amelyeket a szabály képes észlelni:

1. példa

Argumentum nélküli és nem argumentummal rendelkező ReadAsync meghívásokCancellationToken:

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);
        }
    }
}

Javítás

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);
        }
    }
}

2. példa

Argumentum nélküli és argumentummal rendelkező WriteAsync meghívásokCancellationToken:

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);
        }
    }
}

Javítás:

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);
        }
    }
}

3. példa

Meghívások a következővel 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);
        }
    }
}

Javítás:

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);
        }
    }
}

Nem szabálysértések

Az alábbiakban néhány példát mutatunk be olyan meghívásokra, amelyeknél a szabály nem lesz aktiválva.

A visszatérési érték a várt helyett egy Task változóba lesz mentve:

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);
        }
    }
}

A visszatérési értéket a csomagoló metódus adja vissza a várakozás helyett:

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);
    }
}

A visszatérési érték a ContinueWith meghívására szolgál, amely a várt metódust jelenti.

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 => { /* ... */ });
        }
    }
}

Mikor kell letiltani a figyelmeztetéseket?

Nyugodtan figyelmen kívül hagyhatja ezt a szabálysértést, ha nem tartja fontosnak a teljesítmény növelését a pufferek streamalapú osztályokban történő olvasása vagy írása során.

Figyelmeztetés mellőzése

Ha csak egyetlen szabálysértést szeretne letiltani, adjon hozzá előfeldolgozási irányelveket a forrásfájlhoz a szabály letiltásához és újbóli engedélyezéséhez.

#pragma warning disable CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835

Ha le szeretné tiltani egy fájl, mappa vagy projekt szabályát, állítsa annak súlyosságát none a konfigurációs fájlban.

[*.{cs,vb}]
dotnet_diagnostic.CA1835.severity = none

További információ: Kódelemzési figyelmeztetések letiltása.

Lásd még