0Pricing
C# Academy · บทเรียน

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. HashSet , SortedSet , Queue , Stack
  2. ConcurrentDictionary และคอลเลกชันไม่เปลี่ยนแปลง
  3. ความเท่ากันและการแฮช (ค่ากับการอ้างอิง)
← กลับไปที่ C# Academy