
C# Concurrentdictionary (Comment ça fonctionne pour les développeurs)
Lorsqu'on travaille avec des applications multi-thread en C#, maintenir l'intégrité des données est crucial, surtout lorsque vous générez des documents PDF à la volée en utilisant une bibliothèque comme IronPDF. La classe ConcurrentDictionary<tkey, tvalue> fournit une collection sûre pour les threads pour gérer efficacement les paires clé-valeur, même lorsque plusieurs threads effectuent simultanément des opérations telles que des insertions, des mises à jour ou des recherches.
Dans ce guide, nous explorerons comment fonctionne ConcurrentDictionary, comment il peut s'intégrer à IronPDF pour le traitement parallèle des PDF, et ce que chaque développeur .NET doit savoir sur le type de clé, la sécurité des threads, et les pièges courants comme la gestion d'une clé existante ou l'assurance de la cohérence des données.
What is a ConcurrentDictionary in C#?
La classe ConcurrentDictionary<tkey, tvalue>, faisant partie de l'espace de noms System.Collections.Concurrent, est une collection générique conçue pour des opérations performantes et sûres. Contrairement à un dictionnaire ordinaire, elle permet à plusieurs threads d'accéder et de modifier la collection sans verrouiller toute la structure.
Une nouvelle instance de ConcurrentDictionary<string, string> pourrait ressembler à ceci :
var dictionary = new ConcurrentDictionary<string, string>();Dim dictionary = New ConcurrentDictionary(Of String, String)()Vous pouvez définir vos propres types TKey et TValue en fonction de votre cas d'utilisation spécifique, comme la mise en cache des chemins de fichiers PDF rendus ou le suivi des tâches de génération de PDF concurrentes.
Pourquoi utiliser ConcurrentDictionary avec IronPDF?
Imaginez que vous construisez un programme qui génère des factures personnalisées avec IronPDF pour des milliers d'utilisateurs. Si chaque thread doit rendre un document et stocker son résultat, un dictionnaire classique introduirait des conditions de concurrence ou déclencherait des exceptions si une clé existe déjà.
L'utilisation de ConcurrentDictionary assure :
- Cohérence des données entre les threads
- Lectures et écritures efficaces
- Prévention d'erreurs de code inconnues
- Aucun surcoût de verrouillage lorsque plusieurs threads opèrent sur des clés différentes
Méthodes communes et leur utilisation avec IronPDF
Décomposons les méthodes clés en utilisant des scénarios de rendu IronPDF.
Méthode GetOrAdd : Récupérer ou Ajouter une nouvelle clé
Cette méthode vérifie si une clé spécifiée existe. Si ce n'est pas le cas, elle ajoute la nouvelle valeur.
var filePath = pdfCache.GetOrAdd(userId, id => GeneratePdfForUser(id));Dim filePath = pdfCache.GetOrAdd(userId, Function(id) GeneratePdfForUser(id))- Assure la sécurité des threads
- Évite le rendu en double
- Retourne la valeur associée pour la clé donnée
Méthode AddOrUpdate : Gérer une valeur existante avec grâce
Cette méthode vous permet de mettre à jour la valeur si la clé existe, ou d'ajouter une nouvelle paire clé-valeur.
pdfCache.AddOrUpdate(userId,
id => GeneratePdfForUser(id),
(id, existingValue) => UpdatePdfForUser(id, existingValue));pdfCache.AddOrUpdate(userId, Function(id) GeneratePdfForUser(id), Function(id, existingValue) UpdatePdfForUser(id, existingValue))- Gère la logique pour une clé existante
- S'assure que les membres accédés sont sûrs en simultané
Méthode TryAdd : Ajouter si la clé n'existe pas
Cette méthode essaie d'ajouter une valeur et renvoie une valeur booléenne indiquant le succès.
bool added = pdfCache.TryAdd(userId, pdfBytes);
if (!added)
{
Console.WriteLine("PDF already cached.");
}Dim added As Boolean = pdfCache.TryAdd(userId, pdfBytes)
If Not added Then
Console.WriteLine("PDF already cached.")
End If- Parfaite pour éviter les conflits
- La méthode retourne true si l'insertion réussit
Tableau des cas d'utilisation : Méthodes ConcurrentDictionary

Optimiser pour la performance
ConcurrentDictionary prend en charge le réglage via le constructeur :
int concurrencyLevel = 4;
int initialCapacity = 100;
var dictionary = new ConcurrentDictionary<string, byte[]>(concurrencyLevel, initialCapacity);Dim concurrencyLevel As Integer = 4
Dim initialCapacity As Integer = 100
Dim dictionary = New ConcurrentDictionary(Of String, Byte())(concurrencyLevel, initialCapacity)- niveau de concurrence : Nombre de threads attendus (valeur par défaut = niveau de concurrence par défaut)
- capacité initiale : Nombre d'éléments attendus (capacité initiale par défaut)
Un réglage approprié améliore le débit et réduit le contentieux entre les threads multiples.
Prévenir les problèmes avec les conflits de clés et les valeurs par défaut
Lorsqu'une clé n'existe pas, des opérations comme TryGetValue peuvent renvoyer la valeur par défaut pour le type :
if (!pdfCache.TryGetValue(userId, out var pdf))
{
pdf = GeneratePdfForUser(userId); // Second call
}Dim pdf As var
If Not pdfCache.TryGetValue(userId, pdf) Then
pdf = GeneratePdfForUser(userId) ' Second call
End IfCela protège votre code contre des codes inconnus ou des références nulles. Vérifiez toujours une valeur spécifique avant de supposer sa présence.
Exemple pratique : Générateur de rapports IronPDF sûr pour les threads
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using IronPdf;
public class Program
{
static ConcurrentDictionary<string, byte[]> pdfReports =
new ConcurrentDictionary<string, byte[]>();
static void Main(string[] args)
{
// Simulated user list with HTML content
var users = new List<User>
{
new User { Id = "user1", HtmlContent = "<h1>Report for User 1</h1>" },
new User { Id = "user2", HtmlContent = "<h1>Report for User 2</h1>" },
new User { Id = "user3", HtmlContent = "<h1>Report for User 3</h1>" }
};
// Generate PDFs concurrently
var renderer = new ChromePdfRenderer();
Parallel.ForEach(users, user =>
{
var pdf = pdfReports.GetOrAdd(user.Id, id =>
{
var pdfDoc = renderer.RenderHtmlAsPdf(user.HtmlContent);
return pdfDoc.BinaryData;
});
SaveToFile(pdf, $"{user.Id}.pdf");
});
Console.WriteLine("PDF generation complete.");
}
// Utility method to write PDF binary data to file
static void SaveToFile(byte[] pdfBytes, string filePath)
{
File.WriteAllBytes(filePath, pdfBytes);
Console.WriteLine($"Saved: {filePath}");
}
}
// Simple user class with ID and HTML content
public class User
{
public string Id { get; set; }
public string HtmlContent { get; set; }
}Imports System
Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.IO
Imports System.Threading.Tasks
Imports IronPdf
Public Class Program
Private Shared pdfReports As New ConcurrentDictionary(Of String, Byte())()
Shared Sub Main(ByVal args() As String)
' Simulated user list with HTML content
Dim users = New List(Of User) From {
New User With {
.Id = "user1",
.HtmlContent = "<h1>Report for User 1</h1>"
},
New User With {
.Id = "user2",
.HtmlContent = "<h1>Report for User 2</h1>"
},
New User With {
.Id = "user3",
.HtmlContent = "<h1>Report for User 3</h1>"
}
}
' Generate PDFs concurrently
Dim renderer = New ChromePdfRenderer()
Parallel.ForEach(users, Sub(user)
Dim pdf = pdfReports.GetOrAdd(user.Id, Function(id)
Dim pdfDoc = renderer.RenderHtmlAsPdf(user.HtmlContent)
Return pdfDoc.BinaryData
End Function)
SaveToFile(pdf, $"{user.Id}.pdf")
End Sub)
Console.WriteLine("PDF generation complete.")
End Sub
' Utility method to write PDF binary data to file
Private Shared Sub SaveToFile(ByVal pdfBytes() As Byte, ByVal filePath As String)
File.WriteAllBytes(filePath, pdfBytes)
Console.WriteLine($"Saved: {filePath}")
End Sub
End Class
' Simple user class with ID and HTML content
Public Class User
Public Property Id() As String
Public Property HtmlContent() As String
End ClassFichiers enregistrés

Exemple de sortie

Décomposition du code
Cet exemple démontre comment combiner ConcurrentDictionary<TKey, TValue> avec IronPDF pour générer des PDFs en toute sécurité. C'est parfait pour les applications où plusieurs threads traitent et mettent en cache des fichiers PDF simultanément.
Pourquoi ConcurrentDictionary?
-
Assure un accès sûr aux paires clé-valeur.
-
GetOrAdd()évite la génération de PDF en double. -
Pas de verrouillage manuel nécessaire — parfait pour une forte concurrence. Comment ça fonctionne
-
Une liste d'utilisateurs dispose chacun d'un ID et HTML.
-
Parallel.ForEach spawn des threads pour générer des PDFs.
-
Chaque thread utilise
GetOrAdd()pour soit récupérer, soit créer le PDF. -
Le PDF est sauvegardé en utilisant l'ID de l'utilisateur comme nom de fichier. Résumé
Ce modèle est idéal lorsque :
- Vous générez des PDFs pour de nombreux utilisateurs en même temps.
- Vous avez besoin de performance et de sécurité en matière de threads.
- Vous voulez une concurrence propre, fiable en C#.
Méthodes d'extension et modèles d'accès
Bien que ConcurrentDictionary n'expose pas toutes les fonctionnalités de LINQ, vous pouvez toujours utiliser des méthodes d'extension pour interroger les valeurs :
var completedKeys = pdfReports.Keys.Where(k => k.StartsWith("done-")).ToList();Dim completedKeys = pdfReports.Keys.Where(Function(k) k.StartsWith("done-")).ToList()Cependant, évitez de vous fier aux éléments copiés pendant l'itération car le dictionnaire peut changer. Utilisez .ToList() ou .ToArray() pour travailler avec un instantané si nécessaire.
Conclusion : Sécurité des threads et automatisation PDF
Le ConcurrentDictionary<TKey, TValue> est idéal pour les scénarios où plusieurs threads doivent lire/écrire des paires clé-valeur simultanément—en faisant un compagnon parfait pour IronPDF dans des applications multi-thread.
Que vous mettiez en cache des PDF rendus, suiviez le statut des tâches ou empêchiez des opérations redondantes, l'utilisation de cette collection sécurisée pour les threads garantit que votre logique s'adapte avec performance et fiabilité.
Essayez IronPDF Aujourd'hui
Prêt à construire des applications PDF performantes avec une sécurité complète des threads ? Téléchargez une version d'essai gratuite d'IronPDF et découvrez la génération de PDF sans faille combinée à la puissance de ConcurrentDictionary de C#.

Jacob Mellor est directeur de la technologie chez Iron Software et un ingénieur visionnaire pionnier de la technologie C# PDF. En tant que développeur à l'origine de la base de code centrale d'Iron Software, il a façonné l'architecture des produits de l'entreprise depuis sa création, la transformant aux côtés du PDG Cameron Rimington en une entreprise de plus de 50 personnes au service de la NASA, de Tesla et d'agences gouvernementales mondiales.
Articles connexes


