Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Tạo wrapper đồng bộ hóa cho Hashtable trong C#

Giới thiệu

Hashtable.Synchronized(Hashtable) trả về wrapper an toàn luồng (thread-safe) cho Hashtable. Hashtable gốc không đồng bộ hóa (IsSynchronized = false).

Ví dụ 1: Hashtable gốc không đồng bộ

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        Hashtable hash = new Hashtable();
        hash.Add("1", "AB");
        hash.Add("2", "CD");
        hash.Add("3", "EF");
        hash.Add("4", "GH");
        hash.Add("5", "IJ");
        hash.Add("6", "KL");
        
        Console.WriteLine("Hashtable elements...");
        foreach (DictionaryEntry d in hash)
        {
            Console.WriteLine("Key = " + d.Key + ", Value = " + d.Value);
        }
        
        Console.WriteLine("Hashtable is synchronized? = " + hash.IsSynchronized);
    }
}

Kết quả

Hashtable elements...
Key = 1, Value = AB
Key = 2, Value = CD
Key = 3, Value = EF
Key = 4, Value = GH
Key = 5, Value = IJ
Key = 6, Value = KL
Hashtable is synchronized? = False

Ví dụ 2: Tạo wrapper Synchronized

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        Hashtable hash = new Hashtable();
        hash.Add("1", "Mark");
        hash.Add("2", "Gary");
        hash.Add("3", "Jacob");
        hash.Add("4", "Andy");
        hash.Add("5", "Jack");
        
        Console.WriteLine("Hashtable elements...");
        foreach (DictionaryEntry d in hash)
        {
            Console.WriteLine("Key = " + d.Key + ", Value = " + d.Value);
        }
        
        Console.WriteLine("Hashtable is synchronized? = " + hash.IsSynchronized);
        
        Hashtable hash2 = Hashtable.Synchronized(hash);
        Console.WriteLine("Hashtable is synchronized? = " + hash2.IsSynchronized);
    }
}

Kết quả

Hashtable elements...
Key = 1, Value = Mark
Key = 2, Value = Gary
Key = 3, Value = Jacob
Key = 4, Value = Andy
Key = 5, Value = Jack
Hashtable is synchronized? = False
Hashtable is synchronized? = True

Lưu ý quan trọng về Synchronized Wrapper

  • Wrapper khóa (lock) toàn bộ Hashtable cho mỗi operation
  • Duyệt (enumeration) KHÔNG an toàn luồng ngay cả với wrapper!
  • Phải lock thủ công khi duyệt: lock(hash2.SyncRoot) { foreach... }
  • Hiệu suất kém do lock toàn bộ
// ĐÚNG - Lock khi duyệt
Hashtable syncHash = Hashtable.Synchronized(hash);
lock (syncHash.SyncRoot)
{
    foreach (DictionaryEntry entry in syncHash)
    {
        // An toàn
    }
}

// SAI - Không lock khi duyệt
foreach (DictionaryEntry entry in syncHash) // Không an toàn!
{
    // Có thể ném exception hoặc dữ liệu hỏng
}

Khuyến nghị hiện đại

Thay vì Hashtable + Synchronized, hãy dùng:

  • ConcurrentDictionary<TKey, TValue> (namespace System.Collections.Concurrent) - lock-free, hiệu suất cao
  • Dictionary<TKey, TValue> + lock thủ công cho đơn giản
  • ImmutableDictionary<TKey, TValue> cho read-only thread-safe