Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

สร้าง Wrapper ซิงโครไนซ์สำหรับ ArrayList ใน C#

ภาพรวม

เมธอด static ArrayList.Synchronized(ArrayList) คืนค่า wrapper ที่เป็น thread-safe สำหรับ ArrayList ที่ส่งเข้า ให้การเข้าถึงจากหลายเธรดได้ปลอดภัย

ตัวอย่างที่ 1: ArrayList ธรรมดา (ไม่ synchronized)

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        ArrayList arrList = new ArrayList();
        arrList.Add("AB");
        arrList.Add("CD");
        arrList.Add("EF");
        arrList.Add("GH");
        arrList.Add("IJ");
        arrList.Add("KL");
        Console.WriteLine("ArrayList elements...");
        foreach(string str in arrList)
        {
            Console.WriteLine(str);
        }
        Console.WriteLine("ArrayList is synchronized? = " + arrList.IsSynchronized);
    }
}

ผลลัพธ์

ArrayList elements...
AB
CD
EF
GH
IJ
KL
ArrayList is synchronized? = False

ตัวอย่างที่ 2: สร้าง Synchronized Wrapper

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        ArrayList arrList = new ArrayList();
        arrList.Add("AB");
        arrList.Add("CD");
        arrList.Add("EF");
        arrList.Add("GH");
        arrList.Add("IJ");
        arrList.Add("KL");
        Console.WriteLine("ArrayList elements...");
        foreach(string str in arrList)
        {
            Console.WriteLine(str);
        }
        Console.WriteLine("ArrayList is synchronized? = " + arrList.IsSynchronized);
        ArrayList arrList2 = ArrayList.Synchronized(arrList);
        Console.WriteLine("ArrayList is synchronized? = " + arrList2.IsSynchronized);
    }
}

ผลลัพธ์

ArrayList elements...
AB
CD
EF
GH
IJ
KL
ArrayList is synchronized? = False
ArrayList is synchronized? = True

คำอธิบายเพิ่มเติม

  • Synchronized wrapper ล็อกทุกเมธอด public (Add, Remove, Insert, indexer, Count, ฯลฯ)
  • การวนลูป (foreach) ไม่ได้ thread-safe** แม้ wrapper จะ synchronized ต้องล็อกด้วยตัวเอง:
lock(arrList2.SyncRoot)
{
    foreach(var item in arrList2) { ... }
}
  • ArrayList เป็น legacy ใช้ List<T> + lock หรือ ConcurrentBag<T>/ConcurrentQueue<T> แทน
  • SyncRoot property ให้ออบเจ็กต์สำหรับ lock (pattern มาตรฐานของ ICollection)