Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
| Proprietà | valore |
|---|---|
| Nome tipo | PreferStreamAsyncMemoryOverloads |
| ID regola | CA1835 |
| Title | Preferisce gli overload basati sulla memoria dei metodi ReadAsync/WriteAsync nelle classi basate su flusso |
| Categoria | Prestazioni |
| La correzione causa un'interruzione o meno | Non rompente |
| Abilitato per impostazione predefinita in .NET 10 | Come suggerimento |
| Linguaggi applicabili | C# e Visual Basic |
Causa
Questa regola individua le chiamate attese degli overload dei metodi basati su array di byte per ReadAsync e WriteAsync, e suggerisce di utilizzare gli overload dei metodi basati sulla memoria, perché sono maggiormente efficienti.
Descrizione regola
Gli overload dei metodi basati sulla memoria hanno un utilizzo della memoria più efficiente rispetto a quelli basati su array di byte.
La regola funziona su ReadAsync e WriteAsync invocazioni di qualsiasi classe che eredita da Stream.
La regola funziona solo quando il metodo è preceduto dalla await parola chiave .
| Metodo rilevato | Metodo suggerito |
|---|---|
| ReadAsync(Byte[], Int32, Int32, CancellationToken) | ReadAsync(Memory<Byte>, CancellationToken) |
| ReadAsync(Byte[], Int32, Int32) |
ReadAsync(Memory<Byte>, CancellationToken) con CancellationToken impostato su default in C# o Nothing in Visual Basic. |
| WriteAsync(Byte[], Int32, Int32, CancellationToken) | WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) |
| WriteAsync(Byte[], Int32, Int32) |
WriteAsync(ReadOnlyMemory<Byte>, CancellationToken) con CancellationToken impostato su default in C# o Nothing in Visual Basic. |
Importante
Assicurarsi di passare gli argomenti interi offset e count alle istanze create Memory o ReadOnlyMemory.
Nota
La regola CA1835 è disponibile in tutte le versioni .NET in cui sono disponibili gli overload basati sulla memoria:
- .NET Standard 2.1 e versioni successive.
- .NET Core 2.1 e versioni successive.
Come correggere le violazioni
È possibile correggerli manualmente oppure scegliere di consentire a Visual Studio di farlo automaticamente, passando il mouse sulla lampadina visualizzata accanto alla chiamata al metodo e selezionando la modifica suggerita. Esempio:
La regola può rilevare un'ampia gamma di violazioni per i ReadAsync metodi e WriteAsync . Ecco alcuni esempi dei casi che la regola può rilevare:
Esempio 1
Chiamate di ReadAsync, senza e con un CancellationToken argomento:
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);
}
}
}
Correzione:
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);
}
}
}
Esempio 2
Chiamate di WriteAsync, senza e con un CancellationToken parametro:
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);
}
}
}
Correzione:
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);
}
}
}
Esempio 3
Chiamate con 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);
}
}
}
Correzione:
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 violazioni
Di seguito sono riportati alcuni esempi di chiamate in cui la regola non verrà attivata.
Il valore restituito viene salvato in una Task variabile anziché essere atteso:
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);
}
}
}
Il valore restituito viene restituito dal metodo di wrapping anziché essere atteso:
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);
}
}
Il valore restituito viene usato per chiamare ContinueWith, ovvero il metodo in attesa:
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 => { /* ... */ });
}
}
}
Quando eliminare gli avvisi
È sicuro sopprimere una violazione di questa regola se non ci si preoccupa di migliorare le prestazioni durante la lettura o scrittura di buffer nelle classi basate su stream.
Eliminare un avviso
Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.
#pragma warning disable CA1835
// The code that's violating the rule is on this line.
#pragma warning restore CA1835
Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none su nel file di configurazione.
[*.{cs,vb}]
dotnet_diagnostic.CA1835.severity = none
Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.