ConcurrentDictionary<T> และคอลเลกชันไม่เปลี่ยนแปลง
ใช้ ConcurrentDictionary เพื่ออัปเดตข้อมูลอย่างปลอดภัยต่อเธรด และเรียนรู้แนวทางง่าย ๆ สำหรับข้อมูลที่ไม่เปลี่ยนแปลง เช่น มุมมองอ่านอย่างเดียวและการคัดลอกเมื่อเขียน
ConcurrentDictionary<T> และคอลเลกชันไม่เปลี่ยนแปลง เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน
พื้นฐานความปลอดภัยระหว่างเธรดและการไม่เปลี่ยนแปลง
หัวข้อวันนี้:
- ConcurrentDictionary<TKey,TValue>: อัปเดตอย่างปลอดภัยจากหลายเธรด
- มุมมอง อ่านอย่างเดียว เทียบกับการไม่เปลี่ยนแปลงอย่างแท้จริง
- แนวคิด คัดลอกเมื่อเขียนเพื่อความปลอดภัยแบบเรียบง่าย
การดำเนินการแบบอะตอมิก: GetOrAdd/AddOrUpdate
ใช้ GetOrAdd และ AddOrUpdate สำหรับการดำเนินการแบบอะตอมิก และใช้ TryGetValue เพื่ออ่านข้อมูลอย่างปลอดภัย
using System;
using System.Collections.Concurrent;
public class Program
{
public static void Main(string[] args)
{
ConcurrentDictionary<string, int> counts = new ConcurrentDictionary<string, int>();
// Add if missing
int a = counts.GetOrAdd("apple", 0); // 0
// Increment safely
int newVal = counts.AddOrUpdate("apple", 1, (key, oldValue) => oldValue + 1);
Console.WriteLine("apple was " + a + ", now " + newVal);
int value;
bool ok = counts.TryGetValue("apple", out value);
Console.WriteLine("Has apple? " + ok + " -> " + value);
}
}
แนวคิดการเพิ่มค่าโดยไม่มีสภาวะแข่งขัน
AddOrUpdate หลีกเลี่ยงสภาวะแข่งขันแบบอ่าน-แก้ไข-เขียนที่เกิดขึ้นบ่อย โดยอัปเดตข้อมูลแบบอะตอมิก
using System;
using System.Collections.Concurrent;
public class Program
{
static int Inc(int oldValue) { return oldValue + 1; }
public static void Main(string[] args)
{
ConcurrentDictionary<string, int> clicks = new ConcurrentDictionary<string, int>();
// Simulate multiple updates
for (int i = 0; i < 5; i++)
{
clicks.AddOrUpdate("home", 1, delegate(string k, int v) { return Inc(v); });
}
Console.WriteLine("home clicks = " + clicks["home"]); // 5 (starting at 1 then +4)
}
}
มุมมองอ่านอย่างเดียว (ไม่ใช่การไม่เปลี่ยนแปลง)
AsReadOnly จะส่งคืน มุมมองอ่านอย่างเดียว ไม่ใช่คอลเลกชันที่ไม่เปลี่ยนแปลงอย่างแท้จริง การเปลี่ยนแปลงแหล่งข้อมูลจะแสดงในมุมมองนี้
using System;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
List<string> items = new List<string>(new string[] { "A", "B" });
var ro = items.AsReadOnly(); // ReadOnlyCollection<string>
foreach (string s in ro) Console.WriteLine(s); // A, B
// ro.Add("C"); // not available: read-only view has no Add
// But changing the source list reflects in the view:
items.Add("C");
Console.WriteLine("After source change:");
foreach (string s in ro) Console.WriteLine(s); // A, B, C
}
}
สำเนาสถานะด้วยการคัดลอกเมื่อเขียน
คัดลอกเมื่อเขียน: ส่งคืนรายการใหม่เมื่อมีการเปลี่ยนแปลง ผู้เรียกที่ยังเก็บรายการเดิมไว้จะเห็นสำเนาสถานะที่คงที่
using System;
using System.Collections.Generic;
public class Program
{
static List<int> AddWithoutTouchingOriginal(List<int> original, int item)
{
// create a copy and modify the copy
List<int> copy = new List<int>(original);
copy.Add(item);
return copy;
}
public static void Main(string[] args)
{
List<int> a = new List<int>(new int[] { 1, 2 });
List<int> b = AddWithoutTouchingOriginal(a, 3);
Console.WriteLine("Original:");
foreach (int x in a) Console.WriteLine(x); // 1,2
Console.WriteLine("Copy:");
foreach (int x in b) Console.WriteLine(x); // 1,2,3
}
}
เคล็ดลับและข้อแลกเปลี่ยน
เคล็ดลับ:
- ใช้ ConcurrentDictionary สำหรับตัวนับหรือแคชที่ใช้ร่วมกัน
- AsReadOnly ช่วยป้องกันไม่ให้ผู้ใช้แก้ไขข้อมูลโดยไม่ตั้งใจ
- หากต้องการมุมมองที่คงที่ ให้คัดลอกรายการก่อนแก้ไข
- คอลเลกชันที่ไม่เปลี่ยนแปลงอย่างแท้จริงอยู่ใน System.Collections.Immutable (แพ็กเกจ) แต่ไม่ได้ใช้ที่นี่เพื่อให้โค้ดทำงานได้ในตัว
การเลือกพจนานุกรมที่ปลอดภัยต่อเธรด
สรุป
สรุป: ใช้ ConcurrentDictionary สำหรับการอัปเดตพร้อมกัน เปิดเผย มุมมองอ่านอย่างเดียว ให้ผู้เรียก และใช้ การคัดลอกเมื่อเขียน เมื่อต้องการสำเนาสถานะที่คงที่
คำถามที่พบบ่อย
บทเรียน “ConcurrentDictionary<T> และคอลเลกชันไม่เปลี่ยนแปลง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ConcurrentDictionary<T> และคอลเลกชันไม่เปลี่ยนแปลง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ConcurrentDictionary<T> และคอลเลกชันไม่เปลี่ยนแปลง”
ใช้ ConcurrentDictionary เพื่ออัปเดตข้อมูลอย่างปลอดภัยต่อเธรด และเรียนรู้แนวทางง่าย ๆ สำหรับข้อมูลที่ไม่เปลี่ยนแปลง เช่น มุมมองอ่านอย่างเดียวและการคัดลอกเมื่อเขียน คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน
บทเรียน “ConcurrentDictionary<T> และคอลเลกชันไม่เปลี่ยนแปลง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- HashSet , SortedSet , Queue , Stack
- ConcurrentDictionary และคอลเลกชันไม่เปลี่ยนแปลง
- ความเท่ากันและการแฮช (ค่ากับการอ้างอิง)