Passer au contenu du pied de page
.NET AIDE

Liste concurrente C# (Comment ça fonctionne pour les développeurs)

Si vous avez déjà eu plusieurs threads se bagarrant pour accéder à une ressource partagée, vous savez qu'une implémentation sûre pour les threads n'est pas un jeu. Ne vous inquiétez pas ! C# vous couvre avec les collections concurrentes - une suite puissante de classes de collection génériques et sûres pour les threads qui assurent la sécurité d'exécution avec style et grâce.

Sécurité des Threads et Collections Concurrentes en C

Commençons par imaginer une intersection animée de la ville sans feux de circulation. Vous pouvez imaginer le chaos ! Ceci est similaire à ce qui se passe lorsque plusieurs threads accèdent simultanément à une ressource partagée sans un système approprié en place. Heureusement, en C#, nous avons des feux de circulation pour nos threads - ceux-ci s'appellent collections concurrentes. Ce sont des classes de collection qui n'autorisent qu'un seul thread à accéder à une ressource à la fois. Cette sécurité d'exécution est cruciale lorsque l'on travaille avec plusieurs threads.

Explorer les Collections Concurrentes Sûres pour les Threads en C

En C#, l'espace de noms System.Collections.Concurrent dispose de diverses classes de collection concurrentes, telles que ConcurrentDictionary, ConcurrentQueue, ConcurrentStack, et ConcurrentBag. Ces classes de collection non ordonnées fournissent une version sûre pour les threads de leurs homologues non concurrents. Ce qui distingue les collections concurrentes, c'est qu'elles sont des collections concurrentes non ordonnées, ce qui signifie que les éléments n'ont pas un ordre spécifique. Par exemple, avec une liste concurrente, vous ne savez pas exactement où un élément est inséré. L'accent est mis sur la garantie de sécurité de l'exécution, pas sur le maintien de l'ordre.

Prenons un exemple réel. Pensez à un post de soumission de mot de passe sur un site Web. Avec une collection concurrente, plusieurs utilisateurs peuvent soumettre leurs mots de passe simultanément. Chaque action de 'soumission' est comme un thread, et la collection concurrente garantit que chaque soumission est sûre pour les threads, traitée en toute sécurité et efficacement.

ConcurrentDictionary : Un Exemple Concret

Maintenant, explorons la classe de collection ConcurrentDictionary avec un exemple réel. Imaginez une librairie en ligne avec une fonctionnalité de recommandation. Chaque clic d'utilisateur ajoute un livre à leur liste de recommandations personnelle, représentée par un dictionnaire. Alors que plusieurs utilisateurs naviguent et cliquent sur les livres en même temps, nous avons plusieurs threads accédant simultanément au dictionnaire.

Un ConcurrentDictionary en C# ressemblerait à ceci :

using System.Collections.Concurrent;

ConcurrentDictionary<string, string> recommendedBooks = new ConcurrentDictionary<string, string>();
using System.Collections.Concurrent;

ConcurrentDictionary<string, string> recommendedBooks = new ConcurrentDictionary<string, string>();
Imports System.Collections.Concurrent

Private recommendedBooks As New ConcurrentDictionary(Of String, String)()
$vbLabelText   $csharpLabel

Pour ajouter un livre à la collection complète de recommandations d'un utilisateur, nous pourrions utiliser la méthode TryAdd :

public void Insert(string user, string book)
{
    // Try to add the book to the user's recommendations
    recommendedBooks.TryAdd(user, book);
}
public void Insert(string user, string book)
{
    // Try to add the book to the user's recommendations
    recommendedBooks.TryAdd(user, book);
}
Public Sub Insert(ByVal user As String, ByVal book As String)
	' Try to add the book to the user's recommendations
	recommendedBooks.TryAdd(user, book)
End Sub
$vbLabelText   $csharpLabel

Dans ce scénario, la classe de collection ConcurrentDictionary garantit que chaque clic (ou 'thread') est traité individuellement, donc aucune recommandation de deux utilisateurs ne sera mélangée. Elle gère toute la sécurité des threads, vous n'avez donc pas à vous soucier des courses aux données et d'autres problèmes de concurrence liés à plusieurs threads.

Implémenter des Opérations Sûres pour les Threads

Outre TryAdd, les collections concurrentes en C# fournissent une variété d'autres opérations sûres pour les threads telles que TryRemove et TryUpdate. Ces méthodes garantissent qu'un seul thread peut effectuer une opération à la fois. Ainsi, par exemple, si nous voulions retirer un livre des recommandations d'un utilisateur dans l'exemple précédent, nous pourrions utiliser la méthode TryRemove :

public void RemoveAt(string user)
{
    // Attempt to remove the book for the specified user
    string removedBook;
    recommendedBooks.TryRemove(user, out removedBook);
}
public void RemoveAt(string user)
{
    // Attempt to remove the book for the specified user
    string removedBook;
    recommendedBooks.TryRemove(user, out removedBook);
}
Public Sub RemoveAt(ByVal user As String)
	' Attempt to remove the book for the specified user
	Dim removedBook As String = Nothing
	recommendedBooks.TryRemove(user, removedBook)
End Sub
$vbLabelText   $csharpLabel

La méthode TryRemove tentera de supprimer la valeur de la clé fournie (dans ce cas, un utilisateur) et la mettra dans la variable removedBook.

Copier des Collections Concurrentes

Disons maintenant que vous souhaitez copier votre collection concurrente dans un tableau. Les collections concurrentes fournissent une méthode CopyTo pour cet objectif précis :

public void CopyTo()
{
    // Create an array to hold the recommended books
    string[] bookArray = new string[recommendedBooks.Count];

    // Copy the values of the concurrent dictionary to the array
    recommendedBooks.Values.CopyTo(bookArray, 0);
}
public void CopyTo()
{
    // Create an array to hold the recommended books
    string[] bookArray = new string[recommendedBooks.Count];

    // Copy the values of the concurrent dictionary to the array
    recommendedBooks.Values.CopyTo(bookArray, 0);
}
Public Sub CopyTo()
	' Create an array to hold the recommended books
	Dim bookArray(recommendedBooks.Count - 1) As String

	' Copy the values of the concurrent dictionary to the array
	recommendedBooks.Values.CopyTo(bookArray, 0)
End Sub
$vbLabelText   $csharpLabel

Ici, la méthode CopyTo copie tous les livres (valeurs) du dictionnaire concurrent recommendedBooks dans le bookArray.

Collection Sûre pour les Threads

C# fournit également des collections sûres pour les threads, qui sont conçues pour garantir un accès sûr aux ressources partagées dans des environnements multithread. Ces collections, telles que ConcurrentBag, ConcurrentQueue, et ConcurrentStack, offrent des implémentations sûres pour les threads où plusieurs threads peuvent accéder et modifier la collection simultanément sans provoquer de conflits ou de corruption de données.

Elles garantissent la cohérence et l'intégrité en gérant la synchronisation en interne, ce qui les rend idéales pour les scénarios où une collection non ordonnée est suffisante, et la sécurité des threads est d'une importance capitale dans vos applications C#.

Learn More About IronPDF is a popular C# library that allows you to générer des documents PDF à partir de HTML sans effort.

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Bien qu'elle ne semble pas directement liée aux listes concurrentes au premier abord, IronPDF peut compléter vos opérations de collections concurrentes en fournissant un moyen simple de créer des rapports PDF, des journaux, ou tout autre document qui capture les résultats de votre traitement concurrent.

Considérons le scénario où vous avez une application multithread qui effectue un traitement intensif de données. Alors que les threads travaillent leur magie sur les données, vous pourriez vouloir capturer les résultats et générer un rapport PDF pour une analyse plus approfondie ou pour les archives. C'est là qu'intervient IronPDF.

Utiliser IronPDF est aussi simple que d'ajouter la bibliothèque à votre projet et d'utiliser son API pratique. Voici un exemple de comment vous pouvez intégrer IronPDF avec vos opérations de collections concurrentes :

using IronPdf;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

// Create a concurrent dictionary to hold your processed data
ConcurrentDictionary<int, string> processedData = new ConcurrentDictionary<int, string>();

// Define your data list (replace with your actual data source)
List<DataItem> dataList = GetDataList();

// Process your data concurrently and store the results in the dictionary
Parallel.ForEach(dataList, (dataItem) =>
{
    // Process each data item and add the result to the dictionary
    string processedResult = ProcessDataItem(dataItem);
    processedData.TryAdd(dataItem.Id, processedResult);
});

// Generate a PDF report with the processed data
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(BuildHtmlReport(processedData));
pdfDocument.SaveAs("C:\\processed_data_report.pdf");

// Method to retrieve the data list (replace with your actual data source logic)
List<DataItem> GetDataList()
{
    List<DataItem> dataList = new List<DataItem>()
    {
        new DataItem { Id = 1, Name = "Item 1" },
        new DataItem { Id = 2, Name = "Item 2" },
        new DataItem { Id = 3, Name = "Item 3" },
        new DataItem { Id = 4, Name = "Item 4" }
    };
    return dataList;
}

// Method to process each data item and return the result (replace with your actual data processing logic)
string ProcessDataItem(DataItem dataItem)
{
    // Simulating data processing with a delay
    Task.Delay(100).Wait();
    return $"Processed: {dataItem.Name}";
}

// Method to build the HTML report using the processed data (replace with your actual reporting logic)
string BuildHtmlReport(ConcurrentDictionary<int, string> processedData)
{
    string html = "<h1>Processed Data Report</h1><ul>";
    foreach (var kvp in processedData)
    {
        html += $"<li>Item {kvp.Key}: {kvp.Value}</li>";
    }
    html += "</ul>";
    return html;
}

// Placeholder class for your data item (replace with your actual data item class)
public class DataItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    // Add other properties as needed
}
using IronPdf;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;

// Create a concurrent dictionary to hold your processed data
ConcurrentDictionary<int, string> processedData = new ConcurrentDictionary<int, string>();

// Define your data list (replace with your actual data source)
List<DataItem> dataList = GetDataList();

// Process your data concurrently and store the results in the dictionary
Parallel.ForEach(dataList, (dataItem) =>
{
    // Process each data item and add the result to the dictionary
    string processedResult = ProcessDataItem(dataItem);
    processedData.TryAdd(dataItem.Id, processedResult);
});

// Generate a PDF report with the processed data
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(BuildHtmlReport(processedData));
pdfDocument.SaveAs("C:\\processed_data_report.pdf");

// Method to retrieve the data list (replace with your actual data source logic)
List<DataItem> GetDataList()
{
    List<DataItem> dataList = new List<DataItem>()
    {
        new DataItem { Id = 1, Name = "Item 1" },
        new DataItem { Id = 2, Name = "Item 2" },
        new DataItem { Id = 3, Name = "Item 3" },
        new DataItem { Id = 4, Name = "Item 4" }
    };
    return dataList;
}

// Method to process each data item and return the result (replace with your actual data processing logic)
string ProcessDataItem(DataItem dataItem)
{
    // Simulating data processing with a delay
    Task.Delay(100).Wait();
    return $"Processed: {dataItem.Name}";
}

// Method to build the HTML report using the processed data (replace with your actual reporting logic)
string BuildHtmlReport(ConcurrentDictionary<int, string> processedData)
{
    string html = "<h1>Processed Data Report</h1><ul>";
    foreach (var kvp in processedData)
    {
        html += $"<li>Item {kvp.Key}: {kvp.Value}</li>";
    }
    html += "</ul>";
    return html;
}

// Placeholder class for your data item (replace with your actual data item class)
public class DataItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    // Add other properties as needed
}
Imports IronPdf
Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.Threading.Tasks

' Create a concurrent dictionary to hold your processed data
Private processedData As New ConcurrentDictionary(Of Integer, String)()

' Define your data list (replace with your actual data source)
Private dataList As List(Of DataItem) = GetDataList()

' Process your data concurrently and store the results in the dictionary
Parallel.ForEach(dataList, Sub(dataItem)
	' Process each data item and add the result to the dictionary
	Dim processedResult As String = ProcessDataItem(dataItem)
	processedData.TryAdd(dataItem.Id, processedResult)
End Sub)

' Generate a PDF report with the processed data
Dim renderer = New ChromePdfRenderer()
Dim pdfDocument = renderer.RenderHtmlAsPdf(BuildHtmlReport(processedData))
pdfDocument.SaveAs("C:\processed_data_report.pdf")

' Method to retrieve the data list (replace with your actual data source logic)
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'List(Of DataItem) GetDataList()
'{
'	List<DataItem> dataList = New List<DataItem>() { New DataItem { Id = 1, Name = "Item 1" }, New DataItem { Id = 2, Name = "Item 2" }, New DataItem { Id = 3, Name = "Item 3" }, New DataItem { Id = 4, Name = "Item 4" } };
'	Return dataList;
'}

' Method to process each data item and return the result (replace with your actual data processing logic)
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'string ProcessDataItem(DataItem dataItem)
'{
'	' Simulating data processing with a delay
'	Task.Delay(100).Wait();
'	Return string.Format("Processed: {0}", dataItem.Name);
'}

' Method to build the HTML report using the processed data (replace with your actual reporting logic)
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'string BuildHtmlReport(ConcurrentDictionary(Of int, string) processedData)
'{
'	string html = "<h1>Processed Data Report</h1><ul>";
'	foreach (var kvp in processedData)
'	{
'		html += string.Format("<li>Item {0}: {1}</li>", kvp.Key, kvp.Value);
'	}
'	html += "</ul>";
'	Return html;
'}

' Placeholder class for your data item (replace with your actual data item class)
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'public class DataItem
'{
'	public int Id
'	{
'		get;
'		set;
'	}
'	public string Name
'	{
'		get;
'		set;
'	}
'	' Add other properties as needed
'}
$vbLabelText   $csharpLabel

Voici le résultat du code :

Liste Concurrente C# (Comment Ça Fonctionne Pour Les Développeurs) Figure 1 - Sortie

Conclusion

En conclusion, comprendre et utiliser les collections concurrentes en C#, telles que les listes concurrentes, peut grandement améliorer votre capacité à gérer les scénarios de multithreading et à garantir la sécurité des threads dans vos applications. Avec les collections concurrentes, vous pouvez gérer les ressources partagées efficacement, en prévenant les courses aux données et les collisions entre threads.

Intégrer des bibliothèques externes comme IronPDF peut encore améliorer la fonctionnalité des collections concurrentes en permettant la génération de rapports PDF ou de documents esthétiques. IronPDF propose un essai gratuit de sa bibliothèque pour la conversion de HTML en PDF, vous permettant d'explorer ses capacités, et des options de licence à partir de $799.

Questions Fréquemment Posées

Quelles sont les collections concurrentes en C# ?

Les collections concurrentes en C# sont une suite de classes de collections génériques sécurisées par threads qui garantissent la sécurité des threads lorsque plusieurs threads accèdent à des ressources partagées.

Pourquoi la sécurité des threads est-elle importante en C# ?

La sécurité des threads est essentielle en C# pour éviter le chaos et la corruption des données lorsque plusieurs threads accèdent et modifient des ressources partagées simultanément. Elle garantit que les opérations sont exécutées de manière contrôlée.

Comment puis-je créer une liste sécurisée par thread en C# ?

Bien que C# ne fournisse pas directement de classe Liste sécurisée par threads, vous pouvez utiliser d'autres collections concurrentes comme `ConcurrentBag` ou `ConcurrentDictionary` pour des opérations similaires sécurisées par threads.

Qu'est-ce qu'un ConcurrentDictionary en C# ?

Un ConcurrentDictionary en C# est une classe de collection sécurisée par threads dans l'espace de noms `System.Collections.Concurrent`. Elle permet à plusieurs threads d'ajouter, de mettre à jour et de supprimer des paires clé-valeur en toute sécurité.

Comment un ConcurrentDictionary garantit-il la sécurité des threads ?

Un ConcurrentDictionary garantit la sécurité des threads en gérant la synchronisation en interne, permettant ainsi qu'un seul thread effectue des opérations telles qu'ajouter ou supprimer des éléments à la fois.

Comment pouvez-vous ajouter un élément à un ConcurrentDictionary ?

Vous pouvez ajouter un élément à un ConcurrentDictionary en utilisant la méthode TryAdd, qui tente d'ajouter une paire clé-valeur uniquement si la clé n'existe pas déjà dans le dictionnaire.

Quel est le but de la méthode CopyTo dans les collections concurrentes ?

La méthode CopyTo dans les collections concurrentes est utilisée pour copier les éléments de la collection dans un tableau, offrant un moyen de transférer les données de la collection vers un autre format de stockage.

IronPDF peut-il être utilisé pour générer des rapports PDF à partir de données traitées ?

Oui, IronPDF peut être utilisé pour générer des rapports PDF à partir de données traitées par des applications multithread, capturant les résultats des opérations concurrentes.

Comment l'utilisation d'IronPDF améliore-t-elle la fonctionnalité des opérations concurrentes ?

IronPDF améliore les opérations concurrentes en permettant la création de documents PDF à partir de données traitées, offrant un moyen de documenter et de partager les résultats du traitement multithread.

Quel rôle joue IronPDF dans les applications C# multithread ?

IronPDF permet aux développeurs de générer des rapports PDF à partir de données traitées en parallèle, facilitant la consolidation et le partage des résultats des opérations multithread.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite