CA1835: Akış tabanlı sınıflarda ReadAsync/WriteAsync yöntemlerinin bellek tabanlı aşırı yüklemelerini tercih edin

Özellik Değer
Tür adı PreferStreamAsyncMemoryOverloads
Kural Kimliği CA1835
Başlık Akış tabanlı sınıflarda ReadAsync/WriteAsync yöntemlerinin bellek tabanlı aşırı yüklemelerini tercih edin
Kategori Performans
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 8'de varsayılan olarak etkin Öneri olarak

Neden

Bu kural ve WriteAsynciçin bayt dizi tabanlı yöntem aşırı yüklemelerinin beklenen çağrılarını bulur ve daha verimli oldukları için ReadAsync bunun yerine bellek tabanlı yöntem aşırı yüklemelerinin kullanılmasını önerir.

Kural açıklaması

Bellek tabanlı yöntem aşırı yüklemeleri bayt dizi tabanlı olanlardan daha verimli bir bellek kullanımına sahiptir.

Kural, üzerinde ReadAsync çalışır ve WriteAsync öğesinden Streamdevralan herhangi bir sınıfın çağrılarıdır.

Kural yalnızca yöntemin önüne anahtar sözcüğü geçtiğinde await çalışır.

Algılanan yöntem Önerilen yöntem
ReadAsync(Byte[], Int32, Int32, CancellationToken) ReadAsync(Memory<Byte>, CancellationToken)
ReadAsync(Byte[], Int32, Int32) ReadAsync(Memory<Byte>, CancellationToken)CCancellationToken# veya Nothing Visual Basic'te olarak ayarlayındefault.
WriteAsync(Byte[], Int32, Int32, CancellationToken) WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)
WriteAsync(Byte[], Int32, Int32) WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)CCancellationToken# veya Nothing Visual Basic'te olarak ayarlayındefault.

Önemli

ve count tamsayı bağımsız değişkenlerini oluşturulan Memory veya ReadOnlyMemory örneklere geçirmeyi offset unutmayın.

Dekont

Kural CA1835, bellek tabanlı aşırı yüklemelerin kullanılabildiği tüm .NET sürümlerinde kullanılabilir:

  • .NET Standard 2.1 ve üzeri.
  • .NET Core 2.1 ve üzeri.

İhlalleri düzeltme

Bunları el ile düzeltebilir veya yöntem çağrısının yanında görünen ampulün üzerine gelip önerilen değişikliği seçerek Visual Studio'yu sizin için bunu yapmasına izin vekleyebilirsiniz. Örneğin:

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

Kural, ve WriteAsync yöntemleri için ReadAsync çeşitli ihlalleri algılayabilir. Kuralın algılayabileceğiniz servis taleplerinin örnekleri aşağıda verilmiştir:

Örnek 1

bağımsız değişkeniyle CancellationToken ve olmadan öğesinin çağrılarıReadAsync:

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

Düzeltmek:

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

Örnek 2

bağımsız değişkeniyle CancellationToken ve olmadan öğesinin çağrılarıWriteAsync:

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

Düzeltmek:

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

Örnek 3

ile ConfigureAwaitçağrılar:

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

Düzeltmek:

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

İhlal olmayanlar

Aşağıda, kuralın tetiklenmeyeceği çağrılara bazı örnekler verilmiştir.

Dönüş değeri beklenmek yerine bir Task değişkene kaydedilir:

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

Dönüş değeri, beklenmek yerine sarmalama yöntemi tarafından döndürülür:

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

Dönüş değeri, beklenen yöntem olan öğesini çağırmak ContinueWithiçin kullanılır:

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

Uyarıların ne zaman bastırılması gerekiyor?

Akış tabanlı sınıflarda arabellekleri okurken veya yazarken performansı artırmakla ilgilenmiyorsanız, bu kuralın ihlalini gizlemeniz güvenlidir.

Uyarıyı gizleme

Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.

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

Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini noneolarak ayarlayın.

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

Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.

Ayrıca bkz.