CA1835 : Préférer les surcharges basées sur la mémoire des méthodes ReadAsync/WriteAsync dans les classes basées sur un flux
Propriété | Valeur |
---|---|
Nom du type | PreferStreamAsyncMemoryOverloads |
Identificateur de la règle | CA1835 |
Titre | Préférer les surcharges basées sur la mémoire des méthodes ReadAsync/WriteAsync dans les classes basées sur un flux |
Catégorie | Performances |
Le correctif est cassant ou non cassant | Sans rupture |
Activée par défaut dans .NET 9 | À titre de suggestion |
Cause
Cette règle localise les appels attendus des surcharges de méthode basées sur un tableau d’octets pour ReadAsync
et WriteAsync
, et suggère d’utiliser les surcharges de méthode basées sur la mémoire à la place, car elles sont plus efficaces.
Description de la règle
Les surcharges de méthode basées sur la mémoire ont une utilisation de la mémoire plus efficace que celles basées sur un tableau d’octets.
La règle fonctionne sur les appels ReadAsync
et WriteAsync
de toute classe qui hérite de Stream.
La règle fonctionne uniquement quand la méthode est précédée du mot clé await
.
Méthode détectée | Méthode suggérée |
---|---|
ReadAsync(Byte[], Int32, Int32, CancellationToken) | ReadAsync(Memory<Byte>, CancellationToken) |
ReadAsync(Byte[], Int32, Int32) | ReadAsync(Memory<Byte>, CancellationToken) avec CancellationToken défini sur default en C#, ou Nothing en Visual Basic. |
WriteAsync(Byte[], Int32, Int32, CancellationToken) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) |
WriteAsync(Byte[], Int32, Int32) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) avec CancellationToken défini sur default en C#, ou Nothing en Visual Basic. |
Important
Veillez à passer les arguments entiers offset
et count
aux instances Memory
ou ReadOnlyMemory
créées.
Notes
La règle CA1835 est disponible dans toutes les versions de .NET où les surcharges basées sur la mémoire sont disponibles :
- .NET Standard 2.1 et versions ultérieures.
- .NET Core 2.1 et versions ultérieures.
Comment corriger les violations
Vous pouvez les corriger manuellement ou choisir de laisser Visual Studio le faire pour vous. Il vous suffit de pointer sur l’ampoule qui s’affiche à côté de l’appel de méthode et de sélectionner le changement suggéré. Exemple :
La règle peut détecter diverses violations pour les méthodes ReadAsync
et WriteAsync
. Voici des exemples de cas que la règle peut détecter :
Exemple 1
Appels de ReadAsync
, avec et sans argument 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);
}
}
}
Correctif :
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);
}
}
}
Exemple 2
Appels de WriteAsync
, avec et sans argument 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);
}
}
}
Correctif :
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);
}
}
}
Exemple 3
Appels avec 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);
}
}
}
Correctif :
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-violations
Voici quelques exemples d’appels dans lesquels la règle n’est pas déclenchée.
La valeur de retour est enregistrée dans une variable Task
au lieu d’être attendue :
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);
}
}
}
La valeur de retour est renvoyée par la méthode de wrapping au lieu d’être attendue :
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);
}
}
La valeur de retour est utilisée pour appeler ContinueWith
, qui est la méthode attendue :
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 => { /* ... */ });
}
}
}
Quand supprimer les avertissements
Vous pouvez supprimer une violation de cette règle si vous n’avez pas besoin d’améliorer les performances pendant la lecture ou l’écriture des tampons dans les classes basées sur un flux.
Supprimer un avertissement
Si vous voulez supprimer une seule violation, ajoutez des directives de préprocesseur à votre fichier source pour désactiver et réactiver la règle.
#pragma warning disable CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835
Pour désactiver la règle sur un fichier, un dossier ou un projet, définissez sa gravité sur none
dans le fichier de configuration.
[*.{cs,vb}]
dotnet_diagnostic.CA1835.severity = none
Pour plus d’informations, consultez Comment supprimer les avertissements de l’analyse de code.