Share via


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 PreferStreamAsyncMemoryOverloads
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 kompatibilitástörő vagy nem törik Nem törés
Alapértelmezés szerint engedélyezve a .NET 8-ban Javaslatként

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 minden olyan osztályon ReadAsync működik, amelytől WriteAsyncStreamö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)CancellationToken a C# vagy Nothing a Visual Basic értékre van állítvadefault.
WriteAsync(Byte[], Int32, Int32, CancellationToken) WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)
WriteAsync(Byte[], Int32, Int32) WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)CancellationToken a C# vagy Nothing a Visual Basic értékre van állítvadefault.

Fontos

Győződjön meg arról, hogy az és count az offset egész argumentumot á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:

Code fix for CA1835 - Prefer the memory-based overloads of ReadAsync/WriteAsync methods in stream-based classes

A szabály számos szabálysértést képes észlelni a metódusok és WriteAsync a ReadAsync 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ő CancellationToken meghívásokReadAsync:

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

Erősít:

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 nem argumentummal rendelkező CancellationToken meghívásokWriteAsync:

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

Erősít:

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

Erősít:

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 wrapping 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 függvény a visszatérési értéket használja a híváshoz ContinueWith, amely a várt metódus:

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 el lehet tiltani a szabály megsértését, ha nem aggódik a teljesítmény javítása miatt a pufferek streamalapú osztályokban való 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.

Kapcsolódó információk