Đa luồng (Multi Thread) là kỹ thuật lập trình cho phép một chương trình thực hiện nhiều tác vụ cùng lúc nhằm tăng hiệu suất và tiết kiệm thời gian xử lý. Trong bài viết này, chúng ta sẽ cùng tìm hiểu về đa luồng trong C#, cách tạo và quản lý các Thread, cũng như một số lưu ý khi sử dụng đa luồng.

1. Thread trong C# là gì?

Thread là một đường thực thi (execution path) của một chương trình. Mỗi Thread định nghĩa một dòng điều khiển duy nhất. Một chương trình có thể có nhiều Thread chạy song song, mỗi Thread thực hiện một công việc cụ thể.

Trong C#, lớp System.Threading.Thread được sử dụng để làm việc với các Thread. Nó cho phép tạo và truy cập các Thread riêng lẻ trong một ứng dụng đa luồng. Thread đầu tiên được thực thi trong một tiến trình được gọi là Thread chính. Khi chương trình C# bắt đầu thực thi, Thread chính được tạo tự động. Các Thread được tạo bởi sử dụng lớp Thread được gọi là các Thread con của Thread chính.

Bạn có thể truy cập một Thread bằng cách sử dụng thuộc tính CurrentThread của lớp Thread. Dưới đây là một ví dụ minh họa cho sự thực thi của Thread chính trong C#:

using System;
using System.Threading;

namespace StringeeDemo
{
    class Program
    {
        public static void Main()
        {
            Console.WriteLine("Đa luồng trong C#");
            Console.WriteLine("-----------------------------------");
            Thread th = Thread.CurrentThread;
            th.Name = "MainThread";
            Console.WriteLine("Đây là {0}", th.Name);
            Console.ReadKey();
        }
    }
}

2. Vòng đời của Thread trong C#

Vòng đời của một Thread bắt đầu khi một đối tượng của lớp Thread được tạo và kết thúc khi Thread đó được kết thúc hoặc hoàn thành việc thực thi. Dưới đây là các trạng thái đa dạng trong vòng đời của một Thread trong C#:

  • Unstarted State: Là trạng thái khi instance của Thread được tạo, nhưng phương thức Start chưa được gọi.
  • Ready State: Là trạng thái khi Thread đó sẵn sàng để chạy và đợi CPU cycle.
  • Not Runnable State: Là trạng thái khi Thread không thể thực thi, khi:
    • Phương thức Sleep đã được gọi.
    • Phương thức Wait đã được gọi.
    • Bị ngăn chặn bởi hoạt động I/O.
  • Dead State: Là trạng thái khi Thread hoàn thành sự thực thi hoặc bị hủy bỏ.

>>>>> Bài viết liên quan

3. Tạo Thread trong C#

Để tạo một Thread mới, bạn cần khởi tạo một đối tượng của lớp Thread và truyền vào một tham số là một đối tượng của lớp ThreadStart hoặc ParameterizedThreadStart. Lớp ThreadStart là một delegate (ủy quyền) không có tham số, còn lớp ParameterizedThreadStart là một delegate có một tham số kiểu object. Các delegate này chỉ định phương thức mà Thread sẽ thực thi khi được khởi động.

Sau khi tạo Thread, bạn cần gọi phương thức Start để bắt đầu thực thi Thread. Bạn cũng có thể gọi phương thức Start với một tham số kiểu object nếu Thread được tạo bởi delegate ParameterizedThreadStart.

Dưới đây là một ví dụ minh họa cho việc tạo và khởi động một Thread trong C#:

using System;
using System.Threading;

namespace StringeeDemo
{
    class Program
    {
        public static void Main()
        {
            Console.WriteLine("Đa luồng trong C#");
            Console.WriteLine("-----------------------------------");
            Thread th = new Thread(new ThreadStart(DemoThread));
            th.Start();
            Console.WriteLine("Thread chính tiếp tục chạy...");
            Console.ReadKey();
        }

        static void DemoThread()
        {
            Console.WriteLine("Thread con bắt đầu chạy...");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(i);
                Thread.Sleep(1000);
            }
            Console.WriteLine("Thread con kết thúc...");
        }
    }
}

Kết quả:

Đa luồng trong C#
-----------------------------------
Thread chính tiếp tục chạy...
Thread con bắt đầu chạy...
0
1
2
3
4
Thread con kết thúc...

4. Quản lý Thread trong C#

Trong C#, bạn có thể quản lý các Thread bằng cách sử dụng các thuộc tính và phương thức của lớp Thread. Dưới đây là một số thuộc tính và phương thức phổ biến của lớp Thread:

  • Name: Thuộc tính cho phép đặt hoặc lấy tên của Thread.
  • Priority: Thuộc tính cho phép đặt hoặc lấy mức độ ưu tiên của Thread. Mức độ ưu tiên có thể là Lowest, BelowNormal, Normal, AboveNormal, Highest hoặc TimeCritical.
  • IsBackground: Thuộc tính cho phép đặt hoặc lấy giá trị boolean chỉ ra Thread có phải là Thread nền hay không. Thread nền là Thread sẽ tự động kết thúc khi tất cả các Thread chính kết thúc.
  • IsAlive: Thuộc tính cho phép lấy giá trị boolean chỉ ra Thread có đang chạy hay không.
  • ThreadState: Thuộc tính cho phép lấy trạng thái hiện tại của Thread. Trạng thái có thể là Unstarted, Running, WaitSleepJoin, Suspended, Stopped hoặc Aborted.
  • Join: Phương thức cho phép đợi Thread kết thúc trước khi tiếp tục thực thi Thread hiện tại. Phương thức này có thể có tham số là một số nguyên hoặc một đối tượng TimeSpan chỉ định thời gian tối đa để đợi.
  • Abort: Phương thức cho phép hủy bỏ Thread. Phương thức này sẽ ném ra một ngoại lệ ThreadAbortException trong Thread bị hủy bỏ.
  • Suspend: Phương thức cho phép tạm dừng Thread. Phương thức này đã bị lỗi thời và không nên sử dụng.
  • Resume: Phương thức cho phép tiếp tục Thread đã bị tạm dừng. Phương thức này cũng đã bị lỗi thời và không nên sử dụng.

Dưới đây là một ví dụ minh họa cho việc quản lý Thread trong C#:

using System;
using System.Threading;

namespace StringeeDemo
{
    class Program
    {
        public static void Main()
        {
            Console.WriteLine("Đa luồng trong C#");
            Console.WriteLine("-----------------------------------");
            Thread th1 = new Thread(new ThreadStart(DemoThread1));
            Thread th2 = new Thread(new ThreadStart(DemoThread2));
            th1.Name = "Thread 1";
            th2.Name = "Thread 2";
            th1.Priority = ThreadPriority.Highest;
            th2.Priority = ThreadPriority.Lowest;
            th1.IsBackground = true;
            th2.IsBackground = false;
            Console.WriteLine("Trạng thái của {0} là {1}", th1.Name, th1.ThreadState);
            Console.WriteLine("Trạng thái của {0} là {1}", th2.Name, th2.ThreadState);
            th1.Start();
            th2.Start();
            Console.WriteLine("Trạng thái của {0} là {1}", th1.Name, th1.ThreadState);
            Console.WriteLine("Trạng thái của {0} là {1}", th2.Name, th2.ThreadState);
            th1.Join();
            th2.Join();
            Console.WriteLine("Trạng thái của {0} là {1}", th1.Name, th1.ThreadState);
            Console.WriteLine("Trạng thái của {0} là {1}", th2.Name, th2.ThreadState);
            Console.ReadKey();
        }

        static void DemoThread1()
        {
            Console.WriteLine("{0} bắt đầu chạy...", Thread.CurrentThread.Name);
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("{0} đang chạy...", Thread.CurrentThread.Name);
                Thread.Sleep(500);
            }
            Console.WriteLine("{0} kết thúc...", Thread.CurrentThread.Name);
        }

        static void DemoThread2()
        {
            Console.WriteLine("{0} bắt đầu chạy...", Thread.CurrentThread.Name);
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("{0} đang chạy...", Thread.CurrentThread.Name);
                Thread.Sleep(500);
            }
            Console.WriteLine("{0} kết thúc...", Thread.CurrentThread.Name);
        }
    }
}

Kết quả:

Đa luồng trong C#
-----------------------------------
Trạng thái của Thread 1 là Unstarted
Trạng thái của Thread 2 là Unstarted
Trạng thái của Thread 1 là Running
Trạng thái của Thread 2 là Running
Thread 1 bắt đầu chạy...
Thread 1 đang chạy...
Thread 2 bắt đầu chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 đang chạy...
Thread 2 đang chạy...
Thread 1 kết thúc...
Thread 2 kết thúc...
Trạng thái của Thread 1 là Stopped
Trạng thái của Thread 2 là Stopped

Tổng kết

Trong bài viết này, chúng ta đã cùng tìm hiểu về đa luồng (multi Thread) trong C#, một kỹ thuật lập trình hiệu quả và tiết kiệm thời gian. Chúng ta đã học cách tạo và quản lý các Thread bằng cách sử dụng lớp System.Threading.Thread và các thuộc tính, phương thức của nó. Chúng ta cũng đã thấy một số ví dụ minh họa cho việc sử dụng đa luồng trong C#.

Hy vọng bài viết này sẽ giúp bạn có một cái nhìn tổng quan và cơ bản về đa luồng trong C#. Hẹn gặp lại bạn trong các bài viết sắp tới.


Stringee Communication APIs là giải pháp cung cấp các tính năng giao tiếp như gọi thoại, gọi video, tin nhắn chat, SMS hay tổng đài CSKH cho phép tích hợp trực tiếp vào ứng dụng/website của doanh nghiệp nhanh chóng. Nhờ đó giúp tiết kiệm đến 80% thời gian và chi phí cho doanh nghiệp bởi thông thường nếu tự phát triển các tính năng này có thể mất từ 1 - 3 năm.

Bộ API giao tiếp của Stringee hiện đang được tin dùng bởi các doanh nghiệp ở mọi quy mô, lĩnh vực ngành nghề như TPBank, VOVBacsi24, VNDirect, Shinhan Finance, Ahamove, Logivan, Homedy, Adavigo, bTaskee…

Quý bạn đọc quan tâm xin mời đăng ký NHẬN TƯ VẤN TẠI ĐÂY:    

 Banner bottom