NEWS

[C#] ConcurrentBag là gì và cách sử dụng nó trong lập trình bất đồng bộ

[C#] ConcurrentBag là gì và cách sử dụng nó trong lập trình bất đồng bộ
Đăng bởi: Thảo Meo - Lượt xem: 2823 11:14:26, 06/02/2023C#   In bài viết

Xin chào các bạn, bài viết hôm nay mình sẻ tiếp tục giới thiệu về ConcurrentBag là gì và cách sử dụng nó trong lập trình bất đồng bộ C#.

ConcurrentBag là gì?

ConcurrentBag là một kiểu dữ liệu trong C#, được sử dụng để lưu trữ một tập hợp các phần tử với truy cập đồng thời (concurrent) từ nhiều luồng cùng một lúc.

Nó cung cấp các phương thức để thêm, lấy và kiểm tra phần tử tồn tại trong tập hợp, với việc đảm bảo tính đồng bộ (thread-safe) trong quá trình thực hiện.

ConcurrentBag_csharp

1. Cách tạo một ConcurrentBag collection 

ConcurrentBag<int> bag = new ConcurrentBag<int>();

Đoạn code ở trên là cách khai báo 1 ConcurrentBag.

Hoặc bạn có thể thêm nó từ một danh sách List<int> đang có sẵn như đoạn code dưới:

List<int> ints = new List<int>();
ints.Add(1);
ints.Add(2);
ints.Add(3);
ints.Add(4);

ConcurrentBag<int> bag = new ConcurrentBag<int>(ints);
int count = bag.Count;

2. Cách thêm một item vào ConcurrentBag sử dụng phương thức Add()

ConcurrentBag<int> bag = new ConcurrentBag<int>();
bag.Add(1);
bag.Add(2);

Hoặc thêm nhiều item một lúc từ danh sách một mảng array.

int[] arr = { 1, 2, 3 };

ConcurrentBag<int> bag = new ConcurrentBag<int>();
foreach(var item in arr)
{
    bag.Add(item);
}

Cách đếm tất cả item, chúng ta sử dụng hàm count

ConcurrentBag<int> bag = new ConcurrentBag<int>();
bag.Add(1);
bag.Add(2);

int count = bag.Count; //returns 2

3. Cách duyệt các item trong ConcurrentBag 

Chúng ta sử dụng hàm TryPeek()TryTake()

+ TryPeek() chúng ta sẽ duyệt qua các item nhưng không xóa chúng ra khỏi danh sách ConcurrentBag

ConcurrentBag<int> bag = new ConcurrentBag<int>();
bag.Add(1);
bag.Add(2);

int item;
bool isSucess = bag.TryPeek(out item); //isSuccess=True, item = 2
isSuccess = bag.TryPeek(out item); //isSuccess=True, item = 2
isSuccess = bag.TryPeek(out item); //isSuccess=True, item = 2

+ TryTake() lấy ra từng item và xóa chúng ra khỏi danh sách ConcurrentBag 

ConcurrentBag<int> bag = new ConcurrentBag<int>();
bag.Add(1);
bag.Add(2);

int item;
bool isSuccess = bag.TryTake(out item); //isSuccess=True, item = 2
isSuccess = bag.TryTake(out item); //isSuccess=True, item = 1

4. Ví dụ sử dụng ConcurrentBag sử dụng từ nhiều Thread.

Ví dụ: Chúng ta tạo 2 Thread bao gồm: Thread1 và Thread2.

+ Tại Thread1: chúng ta sẽ thêm vào 4 đối tượng: 1,2,3,4

+ Tại Thread2: chúng ta sẽ thêm vào 3 đối tượng: 5,6,7

Sau khi, Thread1 đã add data vào, chúng ta sẽ xuất dữ liệu từng đối tượng đó ra.

Ở ví dụ code dưới, các bạn sẽ thấy nó sẽ xuất ra màn hình: 1,2,3,4 và chờ đợi Thead2 thêm dữ liệu xong nó sẽ tiếp tục xuất ra tiếp: 5,6,7

static void Main(string[] args)
{
    ConcurrentBag<int> bag = new ConcurrentBag<int>();
    AutoResetEvent autoEvent1 = new AutoResetEvent(false);

    Task t1 = Task.Factory.StartNew(() =>
    {
        for (int i = 1; i <= 4; ++i)
        {
            bag.Add(i);
        }
        //wait for second thread to add its items
        autoEvent1.WaitOne();

        while (bag.IsEmpty == false)
        {
            int item;
            if (bag.TryTake(out item))
            {
                Console.WriteLine(item);
            }
        }
    });


    Task t2 = Task.Factory.StartNew(() =>
        {
            for (int i = 5; i <= 7; ++i)
            {
                bag.Add(i);
            }
            autoEvent1.Set();
        });

    t1.Wait();

    //Output
    // 4
    // 3
    // 2
    // 1
    // 5
    // 6
    // 7
}

Để dễ hiểu, các bạn hãy copy đoạn code trên vào chạy vào Visual Studio để dễ hình dung.

Thanks for watching!

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[C#] ConcurrentBag là gì và cách sử dụng nó trong lập trình bất đồng bộ
Đăng bởi: Thảo Meo - Lượt xem: 2823 11:14:26, 06/02/2023C#   In bài viết

CÁC BÀI CÙNG CHỦ ĐỀ

Đọc tiếp
.