CA1835: Utamakan overload berbasis memori dari metode ReadAsync/WriteAsync di kelas berbasis aliran
Properti | Nilai |
---|---|
Nama jenis | PreferStreamAsyncMemoryOverloads |
ID Aturan | CA1835 |
Judul | Lebih suka kelebihan beban berbasis memori metode ReadAsync/WriteAsync di kelas berbasis aliran |
Golongan | Performa |
Perbaikan bersifat disruptif atau non-disruptif | Non-disruptif |
Diaktifkan secara default di .NET 9 | Sebagai saran |
Penyebab
Aturan ini menemukan pemanggilan yang ditunggu dari overload metode berbasis byte-array untuk ReadAsync
dan WriteAsync
, serta menyarankan penggunaan overload metode berbasis memori, karena lebih efisien.
Deskripsi aturan
Overload metode berbasis memori memiliki penggunaan memori yang lebih efisien daripada yang berbasis array byte.
Aturan ini berfungsi pada pemanggilan ReadAsync
dan WriteAsync
dari kelas apa pun yang mewarisi dari Stream.
Aturan hanya berfungsi ketika metode didahului oleh kata kunci await
.
Metode yang terdeteksi | Metode yang disarankan |
---|---|
ReadAsync(Byte[], Int32, Int32, CancellationToken) | ReadAsync(Memory<Byte>, CancellationToken) |
ReadAsync(Byte[], Int32, Int32) |
ReadAsync(Memory<Byte>, CancellationToken) dengan CancellationToken ditetapkan ke default di C#, atau Nothing di Visual Basic. |
WriteAsync(Byte[], Int32, Int32, CancellationToken) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) |
WriteAsync(Byte[], Int32, Int32) |
WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) dengan CancellationToken ditetapkan ke default di C#, atau Nothing di Visual Basic. |
Penting
Pastikan untuk meneruskan argumen bilangan bulat offset
dan count
ke instans Memory
atau ReadOnlyMemory
yang dibuat.
Catatan
Aturan CA1835 tersedia pada semua versi .NET di mana overload berbasis memori tersedia:
- .NET Standard 2.1 dan yang lebih baru.
- .NET Core 2.1 dan yang lebih baru.
Cara memperbaiki pelanggaran
Anda dapat memperbaikinya secara manual, Atau Anda dapat memilih untuk membiarkan Visual Studio melakukannya untuk Anda, dengan mengarahkan kursor ke bola lampu yang muncul di samping pemanggilan metode, dan memilih perubahan yang disarankan. Contoh:
Aturan ini dapat mendeteksi berbagai pelanggaran untuk metode ReadAsync
dan WriteAsync
. Berikut adalah contoh kasus yang dapat dideteksi oleh aturan:
Contoh 1
Pemanggilan ReadAsync
, tanpa dan dengan argumen CancellationToken
:
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);
}
}
}
Perbaikan:
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);
}
}
}
Contoh 2
Pemanggilan WriteAsync
, tanpa dan dengan argumen CancellationToken
:
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);
}
}
}
Perbaikan:
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);
}
}
}
Contoh 3
Pemanggilan dengan 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);
}
}
}
Perbaikan:
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);
}
}
}
Non-pelanggaran
Berikut beberapa contoh pemanggilan di mana aturan tidak akan diaktifkan.
Nilai pengembalian disimpan dalam variabel Task
alih-alih ditunggu:
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);
}
}
}
Nilai pengembalian dikembalikan oleh metode pembungkusan alih-alih ditunggu:
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);
}
}
Nilai pengembalian digunakan untuk memanggil ContinueWith
, yang merupakan metode yang ditunggu:
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 => { /* ... */ });
}
}
}
Kapan harus menekan peringatan
Aman untuk menyembunyikan pelanggaran aturan ini jika Anda tidak khawatir mengenai peningkatan performa saat membaca atau menulis buffer di kelas berbasis aliran.
Menyembunyikan peringatan
Jika Anda hanya ingin menyembunyikan satu pelanggaran, tambahkan arahan praprosedur ke file sumber Anda untuk dinonaktifkan lalu aktifkan kembali aturannya.
#pragma warning disable CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835
Untuk menonaktifkan aturan untuk file, folder, atau proyek, atur tingkat keparahannya ke none
dalam file konfigurasi.
[*.{cs,vb}]
dotnet_diagnostic.CA1835.severity = none
Untuk informasi selengkapnya, lihat Cara menyembunyikan peringatan analisis kode.