C# Gleichzeitige Liste (Wie es für Entwickler funktioniert)
Wenn Sie jemals mehrere Threads hatten, die um den Zugriff auf eine gemeinsame Ressource konkurrieren, wissen Sie, dass eine threadsichere Implementierung kein Spiel ist. Keine Sorge! C# hat Sie mit konkurrierenden Sammlungen abgedeckt - einer leistungsstarken Suite von thread-sicheren generischen Sammlungsklassen, die die Threadsicherheit stilvoll und elegant gewährleisten.
Thread-Sicherheit und nebenläufige Sammlungen in C
Beginnen wir damit, eine geschäftige Stadtkreuzung ohne Ampeln vorzustellen. Sie können sich das Chaos vorstellen! Dies ist ähnlich wie das, was passiert, wenn mehrere Threads gleichzeitig auf eine gemeinsame Ressource zugreifen, ohne dass ein angemessenes System vorhanden ist. Glücklicherweise haben wir in C# Ampeln für unsere Threads - sie werden parallele Kollektionen genannt. Dies sind Sammlungsklassen, die es nur einem Thread erlauben, gleichzeitig auf eine Ressource zuzugreifen. Diese Thread-Sicherheit ist entscheidend, wenn mit mehreren Threads gearbeitet wird.
Nebenläufige threadsichere Sammlungen in C# erkunden
In C# verfügt der Namespace System.Collections.Concurrent über eine Vielzahl von Klassen für die gleichzeitige Datenerfassung, wie z. B. ConcurrentDictionary, ConcurrentQueue, ConcurrentStack und ConcurrentBag. Diese ungeordneten Sammlungsklassen bieten eine threadsichere Version ihrer nicht-parallelen Gegenstücke. Was parallele Sammlungen auszeichnet, ist, dass sie ungeordnete parallele Sammlungen sind, was bedeutet, dass Elemente keine spezifische Reihenfolge haben. Beispielsweise wissen Sie bei einer parallelen Liste nicht genau, wo ein Element eingefügt wird. Der Fokus liegt auf der Gewährleistung von Thread-Sicherheit, nicht auf der Aufrechterhaltung einer Ordnung.
Lassen Sie uns ein reales Beispiel nehmen. Denken Sie an einen Passwortübermittlungsbeitrag auf einer Website. Mit einer gleichzeitigen Sammlung können mehrere Benutzer ihre Passwörter gleichzeitig übermitteln. Jede 'Absendung' entspricht einem Thread, und die parallele Sammlung sorgt dafür, dass jede Übermittlung threadsicher, sicher und effektiv verarbeitet wird.
ConcurrentDictionary: Ein Beispiel aus der Praxis
Nun wollen wir die Sammlungsklasse ConcurrentDictionary anhand eines praktischen Beispiels genauer betrachten. Stellen Sie sich einen Online-Buchladen mit einer Empfehlungsfunktion vor. Jeder Klick eines Benutzers fügt ein Buch seiner persönlichen Empfehlungsliste hinzu, die durch ein Wörterbuch dargestellt wird. Während mehrere Benutzer gleichzeitig Bücher durchsuchen und anklicken, haben wir mehrere Threads, die gleichzeitig auf das Wörterbuch zugreifen.
Ein ConcurrentDictionary in C# würde etwa so aussehen:
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)()
Um ein Buch zur gesamten Empfehlungssammlung eines Benutzers hinzuzufügen, könnten wir die Methode TryAdd verwenden:
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
In diesem Szenario stellt die Collection-Klasse ConcurrentDictionary sicher, dass jeder Klick (bzw. "Thread") einzeln verarbeitet wird, sodass die Empfehlungen zweier Benutzer nicht vermischt werden. Sie übernimmt die gesamte Thread-Sicherheit, sodass Sie sich keine Gedanken über Datenkonflikte und andere Probleme mit der Parallelverarbeitung mehrerer Threads machen müssen.
Implementierung von thread-sicheren Operationen
Neben TryAdd bieten Concurrent Collections in C# eine Vielzahl weiterer threadsicherer Operationen wie TryRemove und TryUpdate. Diese Methoden stellen sicher, dass jeweils nur ein Thread eine Operation ausführen kann. Wenn wir beispielsweise im vorherigen Beispiel ein Buch aus den Empfehlungen eines Benutzers entfernen wollten, könnten wir die Methode TryRemove verwenden:
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
Die Methode TryRemove versucht, den Wert des angegebenen Schlüssels (in diesem Fall ein Benutzer) zu entfernen und ihn in die Variable removedBook einzufügen.
Kopieren gleichzeitiger Sammlungen
Angenommen, Sie möchten Ihre parallele Sammlung in ein Array kopieren. Gleichzeitige Sammlungen bieten eine CopyTo Methode genau für diesen Zweck:
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
Hier kopiert die Methode CopyTo alle Bücher (Werte) aus dem nebenläufigen Wörterbuch recommendedBooks in das Wörterbuch bookArray.
Threadsichere Sammlung
C# bietet auch thread-sichere Sammlungen, die darauf ausgelegt sind, den sicheren Zugriff auf gemeinsame Ressourcen in Mehrthread-Umgebungen zu gewährleisten. Diese Sammlungen, wie zum Beispiel ConcurrentBag, ConcurrentQueue und ConcurrentStack, bieten threadsichere Implementierungen, bei denen mehrere Threads gleichzeitig auf die Sammlung zugreifen und sie ändern können, ohne dass es zu Konflikten oder Datenbeschädigung kommt.
Sie gewährleisten Konsistenz und Integrität, indem sie die Synchronisation intern handhaben, was sie ideal für Szenarien macht, in denen eine ungeordnete Sammlung ausreicht und Thread-Sicherheit in Ihren C#-Anwendungen von größter Bedeutung ist.
IronPDF ist eine beliebte C#-Bibliothek, die es Ihnen ermöglicht, PDF-Dokumente mühelos aus HTML zu erstellen.
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
Obwohl es auf den ersten Blick nicht direkt im Zusammenhang mit parallelen Listen zu stehen scheint, kann IronPDF Ihre Operationen mit nebenläufigen Sammlungen ergänzen, indem es einen einfachen Weg zum Erstellen von PDF-Berichten, Protokollen oder anderen Dokumenten bietet, die die Ergebnisse Ihrer parallelen Verarbeitung festhalten.
Betrachten Sie das Szenario, in dem Sie eine mehrfädige Anwendung haben, die intensive Datenverarbeitung durchführt. Während die Threads ihre Magie an den Daten entfalten, möchten Sie möglicherweise die Ergebnisse erfassen und einen PDF-Bericht zur weiteren Analyse oder zur Dokumentation erstellen. Hier kommt IronPDF ins Spiel.
Die Verwendung von IronPDF ist so einfach wie das Hinzufügen der Bibliothek zu Ihrem Projekt und die Nutzung ihrer praktischen API. Hier ist ein Beispiel dafür, wie Sie IronPDF mit Ihren Operationen mit parallelen Sammlungen integrieren können:
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
'}
Hier ist die Ausgabe des Codes:

Abschluss
Abschließend kann das Verständnis und die Nutzung von C#-parallelen Sammlungen, wie paralleler Listen, Ihre Fähigkeit zur Handhabung von Mehrthread-Szenarien erheblich verbessern und die Thread-Sicherheit in Ihren Anwendungen gewährleisten. Mit parallelen Sammlungen können Sie gemeinsam genutzte Ressourcen effektiv verwalten und Datenrennen und -kollisionen zwischen Threads verhindern.
Das Integrieren externer Bibliotheken wie IronPDF kann die Funktionalität von parallelen Sammlungen weiter erweitern, indem es die Erstellung optisch ansprechender PDF-Berichte oder -Dokumente ermöglicht. IronPDF bietet eine kostenlose Testversion seiner Bibliothek zur HTML-zu-PDF-Konvertierung an, mit der Sie die Funktionen erkunden können, sowie Lizenzoptionen ab $999.
Häufig gestellte Fragen
Was sind gleichzeitige Sammlungen in C#?
Gleichzeitige Sammlungen in C# sind eine Reihe von threadsicheren, generischen Sammlungsklassen, die die Threadsicherheit gewährleisten, wenn mehrere Threads auf gemeinsame Ressourcen zugreifen.
Warum ist Threadsicherheit wichtig in C#?
Threadsicherheit ist entscheidend in C#, um Chaos und Datenkorruption zu verhindern, wenn mehrere Threads gleichzeitig auf gemeinsame Ressourcen zugreifen und diese ändern. Es stellt sicher, dass Operationen kontrolliert ausgeführt werden.
Wie kann ich eine threadsichere Liste in C# erstellen?
Obwohl C# keine direkt threadsichere List-Klasse bereitstellt, können Sie andere gleichzeitige Sammlungen wie `ConcurrentBag` oder `ConcurrentDictionary` für ähnliche threadsichere Operationen verwenden.
Was ist ein ConcurrentDictionary in C#?
Ein ConcurrentDictionary in C# ist eine threadsichere Sammlungsklasse innerhalb des `System.Collections.Concurrent` Namespace. Es ermöglicht mehreren Threads, sicher Schlüssel-Wert-Paare gleichzeitig hinzuzufügen, zu aktualisieren und zu entfernen.
Wie gewährleistet ein ConcurrentDictionary die Threadsicherheit?
Ein ConcurrentDictionary gewährleistet die Threadsicherheit, indem es die Synchronisation intern handhabt und jeweils nur einem Thread erlaubt, Operationen wie das Hinzufügen oder Entfernen von Elementen auszuführen.
Wie kann man ein Element zu einem ConcurrentDictionary hinzufügen?
Sie können ein Element zu einem ConcurrentDictionary mit der Methode TryAdd hinzufügen, die versucht, ein Schlüssel-Wert-Paar nur hinzuzufügen, wenn der Schlüssel nicht bereits existiert.
Was ist der Zweck der CopyTo-Methode in gleichzeitigen Sammlungen?
Die CopyTo-Methode in gleichzeitigen Sammlungen wird verwendet, um die Elemente der Sammlung in ein Array zu kopieren, wodurch eine Möglichkeit geschaffen wird, Daten von der Sammlung in ein anderes Speicherformat zu übertragen.
Kann IronPDF verwendet werden, um PDF-Berichte aus verarbeiteten Daten zu erstellen?
Ja, IronPDF kann verwendet werden, um PDF-Berichte aus Daten zu erzeugen, die von Multithread-Anwendungen verarbeitet wurden, und die Ergebnisse gleichzeitiger Operationen zu erfassen.
Wie verbessert die Verwendung von IronPDF die Funktionalität von gleichzeitigen Operationen?
IronPDF verbessert gleichzeitige Operationen, indem es die Erstellung von PDF-Dokumenten aus verarbeiteten Daten ermöglicht und somit eine Möglichkeit bietet, die Ergebnisse von Multithread-Verarbeitungen zu dokumentieren und zu teilen.
Welche Rolle spielt IronPDF in Multithread-C#-Anwendungen?
IronPDF ermöglicht es Entwicklern, PDF-Berichte aus parallel verarbeiteten Daten zu erstellen, was es einfacher macht, Ergebnisse aus gleichzeitigen Operationen zu konsolidieren und zu teilen.




