.NET幫助 C# Concurrentdictionary(開發者工作方式) Curtis Chau 更新日期:8月 5, 2025 Download IronPDF NuGet 下載 DLL 下載 Windows 安裝程式 Start Free Trial Copy for LLMs Copy for LLMs Copy page as Markdown for LLMs Open in ChatGPT Ask ChatGPT about this page Open in Gemini Ask Gemini about this page Open in Grok Ask Grok about this page Open in Perplexity Ask Perplexity about this page Share Share on Facebook Share on X (Twitter) Share on LinkedIn Copy URL Email article 在 C# 中,處理多執行緒應用程式時,保持數據完整性至關重要,尤其是當您使用像 IronPDF 這樣的庫即時生成 PDF 文檔時。 The ConcurrentDictionary<tkey, tvalue> class provides a thread-safe collection to manage key and value pairs efficiently, even when multiple threads concurrently perform operations like insertions, updates, or lookups. 在本指南中,我們將探索 ConcurrentDictionary 的工作原理,它如何與 IronPDF 集成進行並行 PDF 處理,以及每個 .NET 開發者需要了解的鍵類型、線程安全性以及如何處理現有鍵或確保數據一致性等常見陷阱。 C# 中的 ConcurrentDictionary 是什麼? ConcurrentDictionary<tkey, tvalue> 類是 System.Collections.Concurrent 命名空間的一部分,是為高性能、線程安全操作設計的通用集合。 與普通字典不同,它允許多個線程安全地訪問和修改集合,而不鎖定整個結構。 一個新的 ConcurrentDictionary<string, string> 實例看起來像這樣: var dictionary = new ConcurrentDictionary<string, string>(); var dictionary = new ConcurrentDictionary<string, string>(); Dim dictionary = New ConcurrentDictionary(Of String, String)() $vbLabelText $csharpLabel 您可以根據具體的使用情況自定義 TKey 和 TValue 類型,例如緩存渲染的 PDF 文件路徑或跟蹤並發 PDF 生成任務。 為什麼使用 ConcurrentDictionary 與 IronPDF? 想像一下您正在構建一個程序,為數千名用戶使用 IronPDF 生成個性化發票。 如果每個線程都需要渲染一個文檔並存儲其結果,普通字典會引入競爭條件或拋出異常(如果鍵已存在)。 使用 ConcurrentDictionary 確保: 線程之間的數據一致性 高效的讀寫操作 防止未知代碼錯誤 多個線程對不同鍵操作時零鎖定開銷 常用方法及其與 IronPDF 的結合使用 讓我們拆解使用 IronPDF 渲染場景的關鍵方法。 GetOrAdd 方法:檢索或添加新鍵 此方法檢查指定鍵是否存在。 如果不存在,則添加新值。 var filePath = pdfCache.GetOrAdd(userId, id => GeneratePdfForUser(id)); var filePath = pdfCache.GetOrAdd(userId, id => GeneratePdfForUser(id)); Dim filePath = pdfCache.GetOrAdd(userId, Function(id) GeneratePdfForUser(id)) $vbLabelText $csharpLabel 確保線程安全 避免重複渲染 返回給定鍵的關聯值 AddOrUpdate 方法:優雅地處理現有值 此方法允許您在鍵存在時更新值,或添加新鍵值對。 pdfCache.AddOrUpdate(userId, id => GeneratePdfForUser(id), (id, existingValue) => UpdatePdfForUser(id, existingValue)); pdfCache.AddOrUpdate(userId, id => GeneratePdfForUser(id), (id, existingValue) => UpdatePdfForUser(id, existingValue)); pdfCache.AddOrUpdate(userId, Function(id) GeneratePdfForUser(id), Function(id, existingValue) UpdatePdfForUser(id, existingValue)) $vbLabelText $csharpLabel 管理現有鍵的邏輯 確保併發訪問成員的安全 TryAdd 方法:如果鍵不存在則添加 該方法嘗試添加一個值並返回指示成功的布爾值。 bool added = pdfCache.TryAdd(userId, pdfBytes); if (!added) { Console.WriteLine("PDF already cached."); } 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 $vbLabelText $csharpLabel 非常適合避免衝突 插入成功時方法返回 true 用例表:ConcurrentDictionary 方法 優化性能 ConcurrentDictionary 支持通過構造函數進行調整: int concurrencyLevel = 4; int initialCapacity = 100; var dictionary = new ConcurrentDictionary<string, byte[]>(concurrencyLevel, initialCapacity); 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) $vbLabelText $csharpLabel concurrencyLevel:預期的線程數量(默認值 = 默認併發等級) initialCapacity:預期的元素數量(默認初始容量) 正確設置它們可以提高吞吐量並減少多個線程之間的競爭。 防止鍵衝突和默認值的問題 當鍵不存在時,像 TryGetValue 這樣的操作可以返回該類型的默認值: if (!pdfCache.TryGetValue(userId, out var pdf)) { pdf = GeneratePdfForUser(userId); // Second call } 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 If $vbLabelText $csharpLabel 這可以保護您的代碼免受未知代碼或空引用的影響。 在假設存在之前,始終檢查特定值。 實用示例:線程安全的 IronPDF 報告生成器 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; } } 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 Class $vbLabelText $csharpLabel 保存的文件 示例輸出 代碼分解 此示例演示如何將 ConcurrentDictionary<TKey, TValue> 與 IronPDF 結合使用以線程安全的方式生成 PDF。 它非常適合多個線程同時處理和緩存 PDF 文件的應用程序。 為什麼選擇 ConcurrentDictionary? 確保對鍵值對的線程安全訪問。 GetOrAdd() 避免重複的 PDF 生成。 無需手動鎖定——非常適合高併發。 工作原理 用戶列表每個都有一個 ID 和 HTML。 Parallel.ForEach 生成線程來生成 PDF。 每個線程使用 GetOrAdd() 來獲取或創建 PDF。 PDF 使用用戶的 ID 作為文件名保存。 總結 這種模式在以下情況下非常理想: 您同時為許多用戶生成 PDF。 您需要性能 和 線程安全性。 您希望在 C# 中實現乾淨、可靠的併發。 擴展方法和訪問模式 雖然 ConcurrentDictionary 沒有公開所有 LINQ 功能,但您仍然可以使用擴展方法來查詢值: var completedKeys = pdfReports.Keys.Where(k => k.StartsWith("done-")).ToList(); var completedKeys = pdfReports.Keys.Where(k => k.StartsWith("done-")).ToList(); Dim completedKeys = pdfReports.Keys.Where(Function(k) k.StartsWith("done-")).ToList() $vbLabelText $csharpLabel 然而,避免依賴在迭代過程中複製的元素,因為字典可能會發生變化。 如果需要,可以使用 .ToList() 或 .ToArray() 來處理快照。 結論:線程安全與 PDF 自動化的結合 ConcurrentDictionary<TKey, TValue> 在多個線程需要同時讀寫鍵值對的情況下是理想的選擇,使其成為多執行緒應用中IronPDF 的完美伴侶。 無論您是緩存渲染的 PDF、跟踪作業狀態,還是防止冗餘操作,使用這種線程安全的集合都能確保您的邏輯在性能和可靠性上擴展。 立即嘗試 IronPDF 準備好構建具有完整線程安全的高性能 PDF 應用程序了嗎? 下載免費試用版的 IronPDF,體驗無縫 PDF 生成與 C# 的 ConcurrentDictionary 的強大組合。 常見問題解答 ConcurrentDictionary 如何在多线程 C# 应用程序中增强性能? ConcurrentDictionary 通过允许多个线程同时执行插入、更新和查找等操作,而无需外部锁,从而在多线程 C# 应用程序中增强性能,并维护数据完整性。 使用 ConcurrentDictionary 与 IronPDF 的意义是什么? 使用 ConcurrentDictionary 与 IronPDF 具有重要意义,因为它可以在线程安全管理并行 PDF 处理数据,确保在多线程环境下 PDF 生成高效且无数据冲突。 可以使用 ConcurrentDictionary 管理 C# 中的并发 PDF 生成吗? 是的,可以使用 ConcurrentDictionary 来管理 C# 中的并发 PDF 生成,确保操作跨多个线程安全处理,提高 PDF 生成过程的效率和可靠性。 在 C# 中生成 PDF 时,为什么线程安全很重要? 在 C# 中生成 PDF 时,线程安全很重要,以防止数据损坏并确保输出一致性,特别是在多个线程参与动态创建和修改 PDF 文档时。 使用 ConcurrentDictionary 可以同时执行哪些操作? 可以同时执行插入、更新、查找和删除等操作,ConcurrentDictionary 使得它非常适合需要线程安全数据管理的高性能应用程序。 IronPDF 如何处理并发操作? IronPDF 通过利用像 ConcurrentDictionary 这样的线程安全集合来处理并发操作,使得 PDF 处理高效,并在多个线程中管理数据而不危及数据完整性。 在使用 ConcurrentDictionary 时有必要实现外部锁定吗? 不,使用 ConcurrentDictionary 时不需要实现外部锁定,因为它设计为天生线程安全,管理内部的并发操作。 开发人员如何优化 C# 应用程序中的 PDF 处理? 开发人员可以通过将线程安全集合如 ConcurrentDictionary 与 IronPDF 等库集成来优化 C# 应用程序中的 PDF 处理,实现 PDF 文档的高效可靠并行处理。 Curtis Chau 立即與工程團隊聊天 技術作家 Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。 相關文章 更新日期 9月 4, 2025 RandomNumberGenerator C# 使用RandomNumberGenerator C#類可以幫助將您的PDF生成和編輯項目提升至新水準 閱讀更多 更新日期 9月 4, 2025 C#字符串等於(它如何對開發者起作用) 當結合使用強大的PDF庫IronPDF時,開關模式匹配可以讓您構建更智能、更清晰的邏輯來進行文檔處理 閱讀更多 更新日期 8月 5, 2025 C#開關模式匹配(對開發者來說是如何工作的) 當結合使用強大的PDF庫IronPDF時,開關模式匹配可以讓您構建更智能、更清晰的邏輯來進行文檔處理 閱讀更多 CLR C#(開發者工作方式).NET 10 新特性(開發者工作...