Événements
Créer des applications intelligentes
17 mars, 21 h - 21 mars, 10 h
Rejoignez la série de rencontres pour créer des solutions IA évolutives basées sur des cas d’usage réels avec d’autres développeurs et experts.
S’inscrire maintenantCe navigateur n’est plus pris en charge.
Effectuez une mise à niveau vers Microsoft Edge pour tirer parti des dernières fonctionnalités, des mises à jour de sécurité et du support technique.
Vous pouvez utiliser la fonctionnalité Async pour accéder à des fichiers. La fonctionnalité async vous permet d’appeler des méthodes asynchrones sans utiliser de rappels ni fractionner votre code entre plusieurs méthodes ou expressions lambda. Pour rendre le code synchrone asynchrone, il vous suffit d’appeler une méthode asynchrone au lieu d’une méthode synchrone, puis d’ajouter quelques mots clés au code.
Vous pouvez considérer les raisons suivantes pour ajouter de l'asynchrone aux appels d'accès aux fichiers :
Les exemples simples de cette rubrique illustrent File.WriteAllTextAsync et File.ReadAllTextAsync. Pour un contrôle précis des opérations d’E/S de fichier, utilisez la classe FileStream, qui a une option qui entraîne l’exécution d’E/S asynchrones au niveau du système d’exploitation. En utilisant cette option, vous pouvez éviter de bloquer un thread de pool de threads dans de nombreux cas. Pour l’activer, spécifiez l’argument useAsync=true
ou options=FileOptions.Asynchronous
dans l’appel de constructeur.
Vous ne pouvez pas utiliser cette option avec StreamReader et StreamWriter si vous les ouvrez directement en spécifiant un chemin d’accès au fichier. Toutefois, vous pouvez utiliser cette option si vous leur fournissez un Stream ouvert par la classe FileStream. Les appels asynchrones sont plus rapides dans les applications d’interface utilisateur même si un thread de pool de threads est bloqué, car le thread d’interface utilisateur n’est pas bloqué pendant l’attente.
Les exemples suivants écrivent du texte dans un fichier. À chaque instruction await, la méthode s'arrête immédiatement. Quand l’E/S de fichier est terminée, la méthode reprend à l’instruction qui suit l’instruction await. Le modificateur asynchrone se trouve dans la définition de méthodes qui utilisent l’instruction await.
public async Task SimpleWriteAsync()
{
string filePath = "simple.txt";
string text = $"Hello World";
await File.WriteAllTextAsync(filePath, text);
}
public async Task ProcessWriteAsync()
{
string filePath = "temp.txt";
string text = $"Hello World{Environment.NewLine}";
await WriteTextAsync(filePath, text);
}
async Task WriteTextAsync(string filePath, string text)
{
byte[] encodedText = Encoding.Unicode.GetBytes(text);
using var sourceStream =
new FileStream(
filePath,
FileMode.Create, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true);
await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
}
L’exemple d’origine comprend l’instruction await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
, qui est une contraction des deux instructions suivantes :
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
await theTask;
La première instruction retourne une tâche et provoque le début du traitement du fichier. La deuxième instruction avec await provoque la fin immédiate de la méthode et retourne une tâche différente. Quand le traitement du fichier se termine plus loin, l’exécution retourne à l’instruction qui suit l’attente.
Les exemples suivants lisent du texte dans un fichier.
public async Task SimpleReadAsync()
{
string filePath = "simple.txt";
string text = await File.ReadAllTextAsync(filePath);
Console.WriteLine(text);
}
Le texte est mis en mémoire tampon et, dans cet exemple, est placé dans un StringBuilder. Contrairement à l’exemple précédent, l’évaluation de l’instruction await génère une valeur. La méthode ReadAsync retourne un Task<Int32>, de sorte que l’évaluation de l’expression await génère une valeur Int32
numRead
une fois l’opération effectuée. Pour plus d’informations, consultez Types de retour Async (C#).
public async Task ProcessReadAsync()
{
try
{
string filePath = "temp.txt";
if (File.Exists(filePath) != false)
{
string text = await ReadTextAsync(filePath);
Console.WriteLine(text);
}
else
{
Console.WriteLine($"file not found: {filePath}");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
async Task<string> ReadTextAsync(string filePath)
{
using var sourceStream =
new FileStream(
filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize: 4096, useAsync: true);
var sb = new StringBuilder();
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
string text = Encoding.Unicode.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
Les exemples suivants illustrent le traitement parallèle en écrivant 10 fichiers texte.
public async Task SimpleParallelWriteAsync()
{
string folder = Directory.CreateDirectory("tempfolder").Name;
IList<Task> writeTaskList = new List<Task>();
for (int index = 11; index <= 20; ++ index)
{
string fileName = $"file-{index:00}.txt";
string filePath = $"{folder}/{fileName}";
string text = $"In file {index}{Environment.NewLine}";
writeTaskList.Add(File.WriteAllTextAsync(filePath, text));
}
await Task.WhenAll(writeTaskList);
}
Pour chaque fichier, la méthode WriteAsync retourne une tâche qui est ensuite ajoutée à une liste des tâches. L’instruction await Task.WhenAll(tasks);
quitte la méthode et reprend dans cette dernière quand le traitement du fichier est terminé pour toutes les tâches.
L’exemple ferme toutes les instances de FileStream dans un bloc finally
une fois les tâches effectuées. Si chaque FileStream
était plutôt créé dans une instruction using
, FileStream
pourrait être libéré avant que la tâche ne soit terminée.
Toute amélioration des performances provient presque entièrement du traitement parallèle et non du traitement asynchrone. Les avantages du mode asynchrone sont qu'il n'attache pas plusieurs threads et qu'il ne bloque pas le thread d'interface utilisateur.
public async Task ProcessMultipleWritesAsync()
{
IList<FileStream> sourceStreams = new List<FileStream>();
try
{
string folder = Directory.CreateDirectory("tempfolder").Name;
IList<Task> writeTaskList = new List<Task>();
for (int index = 1; index <= 10; ++ index)
{
string fileName = $"file-{index:00}.txt";
string filePath = $"{folder}/{fileName}";
string text = $"In file {index}{Environment.NewLine}";
byte[] encodedText = Encoding.Unicode.GetBytes(text);
var sourceStream =
new FileStream(
filePath,
FileMode.Create, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true);
Task writeTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
sourceStreams.Add(sourceStream);
writeTaskList.Add(writeTask);
}
await Task.WhenAll(writeTaskList);
}
finally
{
foreach (FileStream sourceStream in sourceStreams)
{
sourceStream.Close();
}
}
}
Quand vous utilisez les méthodes WriteAsync et ReadAsync, vous pouvez spécifier un CancellationToken, qui vous permet d’annuler l’opération en cours de route. Pour plus d’informations, consultez Annulation dans les threads managés.
Commentaires sur .NET
.NET est un projet open source. Sélectionnez un lien pour fournir des commentaires :
Événements
Créer des applications intelligentes
17 mars, 21 h - 21 mars, 10 h
Rejoignez la série de rencontres pour créer des solutions IA évolutives basées sur des cas d’usage réels avec d’autres développeurs et experts.
S’inscrire maintenantEntrainement
Module
Utiliser des fichiers et des répertoires dans une application .NET - Training
Découvrez comment utiliser .NET, C# et System.IO pour travailler avec des répertoires, des chemins d’accès, des fichiers et le système de fichiers.
Documentation
Traiter les tâches asynchrones terminées - C#
Découvrez comment utiliser Task.WhenAny en C# pour démarrer plusieurs tâches et traiter leurs résultats à la fin de leur exécution, plutôt que de les traiter dans l’ordre démarré.
Types de retour asynchrones - C#
Découvrez les types de retour que les méthodes asynchrones peuvent avoir en C# avec des exemples de code pour chaque type.
Scénarios de la programmation asynchrone - C#
Découvrez le modèle de programmation asynchrone au niveau du langage C# fourni par .NET Core.