# C# - Multithreading: Hướng dẫn cho người mới bắt đầu

Xin chào các bạnfuture nhà phát triển C#! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của multithreading. Đừng lo lắng nếu điều này听起来 đáng sợ - tôi sẽ là người hướng dẫn thân thiện của bạn, và chúng ta sẽ cùng nhau bước từng bước. Cuối cùng của hướng dẫn này, bạn sẽ có thể threading như một chuyên gia!

## Multithreading là gì?

Trước khi chúng ta bắt đầu, hãy hiểu multithreading là gì. Hãy tưởng tượng bạn đang nấu một bữa ăn phức tạp. Bạn sẽ không chỉ làm một nhiệm vụ tại một thời điểm, phải không? Bạn có thể đun pasta trên một bếp trong khi bạn đang băm rau và để ý đến nước sốt. Đó là multitasking, và trong thế giới lập trình, chúng ta gọi nó là multithreading.

Multithreading cho phép một chương trình thực hiện nhiều nhiệm vụ cùng một lúc. Nó giống như có nhiều đầu bếp trong nhà bếp, mỗi người chịu trách nhiệm một phần khác nhau của bữa ăn.

## Vòng đời của Thread

Như chúng ta, các thread cũng có vòng đời. Hãy phân tích nó:

1. **Born (New)**: Thread được tạo ra nhưng chưa bắt đầu.
2. **Ready**: Thread sẵn sàng chạy và chờ đợi thời gian CPU.
3. **Running**: Thread đang thực hiện nhiệm vụ của nó.
4. **Blocked**: Thread tạm thời dừng lại (có thể chờ đợi một tài nguyên nào đó).
5. **Dead**: Thread đã hoàn thành nhiệm vụ của nó và không còn chạy nữa.

Dưới đây là một hình ảnh đơn giản:

New -> Ready -> Running -> Dead ^ | | v <-- Blocked

C# - Multithreading


## Thread chính

Khi bạn khởi động một chương trình C#, nó tự động tạo ra một thread gọi là Main Thread. Nó giống như đầu bếp chính trong ví dụ nhà bếp của chúng ta. Hãy xem nó trong hành động:

```csharp
using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Main Thread: " + Thread.CurrentThread.ManagedThreadId);
    }
}

Khi bạn chạy điều này, bạn sẽ thấy điều gì đó như:

Main Thread: 1

Điều này cho thấy rằng chương trình của chúng ta đang chạy trên Main Thread, luôn có ID là 1.

Các thuộc tính và phương thức của lớp Thread

Lớp Thread trong C# đi kèm với một loạt các thuộc tính và phương thức hữu ích. Hãy xem một số phổ biến nhất:

Thuộc tính/Phương thức Mô tả
ManagedThreadId Lấy ra mã định danh duy nhất cho thread
IsAlive Chỉ ra xem thread này đã được khởi động và chưa kết thúc
Name Lấy hoặc đặt tên của thread
Priority Lấy hoặc đặt ưu tiên lập lịch của thread
Start() Khởi động thread
Sleep() Tạm dừng thread trong một khoảng thời gian xác định
Join() Dừng thread gọi cho đến khi thread này kết thúc

Hãy xem một số trong số này trong hành động:

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(DoWork);
        t.Name = "Worker Thread";
        Console.WriteLine("Starting thread...");
        t.Start();
        t.Join();
        Console.WriteLine("Thread finished");
    }

    static void DoWork()
    {
        Console.WriteLine($"Thread {Thread.CurrentThread.Name} is working");
        Thread.Sleep(1000);
        Console.WriteLine($"Thread {Thread.CurrentThread.Name} finished working");
    }
}

Chương trình này tạo một thread mới, đặt tên cho nó, khởi động nó, chờ nó kết thúc, và sau đó tiếp tục. Kết quả đầu ra sẽ là:

Starting thread...
Thread Worker Thread is working
Thread Worker Thread finished working
Thread finished

Tạo Thread

Tạo thread trong C# giống như thuê các đầu bếp mới cho nhà bếp của chúng ta. Dưới đây là cách chúng ta làm điều đó:

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        // Tạo một thread sử dụng một phương thức có tên
        Thread t1 = new Thread(DoWork);
        t1.Start();

        // Tạo một thread sử dụng một phương thức ẩn danh
        Thread t2 = new Thread(() =>
        {
            Console.WriteLine("Thread 2 is working");
        });
        t2.Start();

        // Tạo một thread với các tham số
        Thread t3 = new Thread(param =>
        {
            Console.WriteLine($"Thread 3 says: {param}");
        });
        t3.Start("Hello from Thread 3!");
    }

    static void DoWork()
    {
        Console.WriteLine("Thread 1 is working");
    }
}

Ví dụ này cho thấy ba cách khác nhau để tạo thread. Chạy nó và xem điều gì xảy ra!

Quản lý Thread

Quản lý thread là rất quan trọng để có multithreading hiệu quả. Hãy xem một số cách để làm điều này:

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(DoWork);
        t.Start();

        // Chờ thread kết thúc
        t.Join();

        // Đặt ưu tiên của thread
        t.Priority = ThreadPriority.Highest;

        // Kiểm tra xem thread có còn sống không
        Console.WriteLine($"Is thread alive? {t.IsAlive}");

        // Đặt thread chính vào giấc ngủ
        Thread.Sleep(1000);
    }

    static void DoWork()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Working... {i}");
            Thread.Sleep(500);
        }
    }
}

Ví dụ này minh họa cách chờ đợi một thread kết thúc, đặt ưu tiên của nó, kiểm tra trạng thái của nó, và làm cho một thread ngủ.

Hủy Thread

Trong C#, chúng ta không thường "hủy" thread thủ công. Thread tự động kết thúc khi chúng hoàn thành công việc của mình hoặc khi ứng dụng thoát. Tuy nhiên, chúng ta có thể yêu cầu một thread dừng lại bằng cách sử dụng phương thức Abort(), mặc dù nó thường không được khuyến khích do các vấn đề tiềm ẩn với việc làm sạch tài nguyên.

Dưới đây là một ví dụ về cách sử dụng Abort(), nhưng hãy nhớ, tốt hơn là thiết kế thread của bạn để hoàn thành một cách tự nhiên:

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(DoWork);
        t.Start();

        Thread.Sleep(2000); // Để thread chạy trong 2 giây

        t.Abort(); // Dừng thread
        Console.WriteLine("Thread aborted");
    }

    static void DoWork()
    {
        while (true)
        {
            Console.WriteLine("Working...");
            Thread.Sleep(500);
        }
    }
}

Điều này sẽ chạy thread trong khoảng 2 giây trước khi dừng nó.

Và đó là tất cả! Bạn đã hoàn thành bài học đầu tiên về multithreading trong C#. Nhớ rằng, giống như học nấu ăn, việc thành thạo multithreading đòi hỏi sự luyện tập. Vậy đừng ngần ngại thử nghiệm với các khái niệm này. Chúc bạn may mắn và hy vọng các thread của bạn luôn chạy mượt mà!

Credits: Image by storyset