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

การเข้าถึง Stack แบบซิงโครไนซ์ (Thread-safe) ใน C#

ภาพรวม

คลาส Stack (non-generic) มีคุณสมบัติ SyncRoot สำหรับล็อกการเข้าถึงแบบ thread-safe ใช้ร่วมกับคำสั่ง lock

ตัวอย่างที่ 1: Stack ของจำนวนเต็ม

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        Stack stack = new Stack();
        stack.Push(100);
        stack.Push(200);
        stack.Push(300);
        stack.Push(400);
        stack.Push(500);

        Console.WriteLine("Stack...");
        foreach (Object ob in stack)
        {
            Console.WriteLine(ob);
        }

        Console.WriteLine("Count of elements = " + stack.Count);

        Console.WriteLine("Synchronize access...");
        lock (stack.SyncRoot)
        {
            foreach (Object ob in stack)
            {
                Console.WriteLine(ob);
            }
        }
    }
}

ผลลัพธ์

Stack...
500
400
300
200
100
Count of elements = 5
Synchronize access...
500
400
300
200
100

ตัวอย่างที่ 2: Stack ของสตริง

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        Stack stack = new Stack();
        stack.Push("Jacob");
        stack.Push("Tim");
        stack.Push("Philips");
        stack.Push("Tom");
        stack.Push("Amy");
        stack.Push("Katie");
        stack.Push("Selena");
        stack.Push("Taylor");
        stack.Push("Justin");

        Console.WriteLine("Stack...");
        foreach (Object ob in stack)
        {
            Console.WriteLine(ob);
        }

        Console.WriteLine("\nSynchronize access...");
        lock (stack.SyncRoot)
        {
            foreach (Object ob in stack)
            {
                Console.WriteLine(ob);
            }
        }
    }
}

ผลลัพธ์

Stack...
Justin
Taylor
Selena
Katie
Amy
Tom
Philips
Tim
Jacob
Synchronize access...
Justin
Taylor
Selena
Katie
Amy
Tom
Philips
Tim
Jacob

สรุป

  • ใช้ lock(stack.SyncRoot) ครอบการวนลูปหรือการอ่าน/เขียนเพื่อความปลอดภัยเธรด
  • สำหรับ generic Stack<T> ก็มี SyncRoot เช่นกัน (ผ่าน interface ICollection)
  • ใน .NET Core / .NET 5+ ควรพิจารณา ConcurrentStack<T> แทน