? Bạn cần thực thi một phương thức bằng một tiểu trình trong thread-pool của bộ thực thi.
» Khai báo một phương thức chứa mã lệnh cần thực thi; phương thức này phải trả về void và chỉ nhận một đối số. Sau đó, tạo một thể hiện của ủy nhiệm System.Threading.WaitCallback tham chiếu đến phương thức này. Tiếp tục, gọi phương thức tĩnh QueueUserWorkItem của lớp System.Threading.ThreadPool, và truyền thể hiện ủy nhiệm đã tạo làm đối số. Bộ thực thi sẽ xếp thể hiện ủy nhiệm này vào hàng đợi và thực thi nó khi một tiểu trình trong thread-pool sẵn sàng.
Nếu ứng dụng sử dụng nhiều tiểu trình có thời gian sống ngắn hay duy trì một số lượng lớn các tiểu trình đồng thời thì hiệu năng có thể giảm sút bởi các chi phí cho việc tạo, vận hành và hủy các tiểu trình. Ngoài ra, trong một hệ thống hỗ-trợ-đa-tiểu-trình, các tiểu trình thường ở trạng thái rỗi suốt một khoảng thời gian dài để chờ điều kiện thực thi phù hợp. Việc sử dụng thread-pool sẽ cung cấp một giải pháp chung nhằm cải thiện tính quy mô và hiệu năng của các hệ thống hỗ-trợ-đa-tiểu-trình.
.NET Framework cung cấp một hiện thực đơn giản cho thread-pool mà chúng ta có thể truy xuất thông qua các thành viên tĩnh của lớp ThreadPool. Phương thức QueueUserWorkItem cho phép bạn thực thi một phương thức bằng một tiểu trình trong thread-pool (đặt công việc vào hàng đợi). Mỗi công việc được mô tả bởi một thể hiện của ủy nhiệm WaitCallback (tham chiếu đến phương thức cần thực thi). Khi một tiểu trình trong thread-pool sẵn sàng, nó nhận công việc kế tiếp từ hàng đợi và thực thi công việc này. Khi đã hoàn tất công việc, thay vì kết thúc, tiểu trình này quay về thread-pool và nhận công việc kế tiếp từ hàng đợi.
Việc sử dụng thread-pool của bộ thực thi giúp đơn giản hóa việc lập trình hỗ-trợ-đa-tiểu-trình. Tuy nhiên, cần lưu ý đây là thread-pool được hiện thực đơn giản, chỉ nhằm mục đích sử dụng chung. Trước khi quyết định sử dụng thread-pool này, cần xem xét các điểm sau:
• Bộ thực thi quy định số tiểu trình tối đa được cấp cho thread-pool; bạn không thể thay đổi số tối đa này bằng các tham số cấu hình hay từ bên trong mã được-quản-lý. Giới hạn mặc định là 25 tiểu trình cho mỗi CPU trong hệ thống. Số tiểu trình tối đa trong thread-pool không giới hạn số các công việc đang chờ trong hàng đợi.
• Cũng như việc cho phép bạn sử dụng thread-pool để thực thi mã lệnh một cách trực tiếp, bộ thực thi còn sử dụng thread-pool cho nhiều mục đích bên trong, bao gồm việc thực thi phương thức một cách bất đồng bộ (xem mục 4.2) và thực thi các sự kiện định thời (xem mục 4.3). Tất cả các công việc này có thể dẫn đến sự tranh chấp giữa các tiểu trình trong thread-pool; nghĩa là hàng đợi có thể trở nên rất dài. Mặc dù độ dài tối đa của hàng đợi chỉ bị giới hạn bởi số lượng bộ nhớ còn lại cho tiến trình của bộ thực thi, nhưng hàng đợi quá dài sẽ làm kéo dài quá trình thực thi của các công việc trong hàng đợi.
• Bạn không nên sử dụng thread-pool để thực thi các tiến trình chạy trong một thời gian dài. Vì số tiểu trình trong thread-pool là có giới hạn, nên chỉ một số ít tiểu trình thuộc các tiến trình loại này cũng sẽ ảnh hưởng đáng kể đến toàn bộ hiệu năng của thread-pool. Đặc biệt, bạn nên tránh đặt các tiểu trình trong thread-pool vào trạng thái đợi trong một thời gian quá dài.
• Bạn không thể điều khiển lịch trình của các tiểu trình trong thread-pool, cũng như không thể thay đổi độ ưu tiên của các công việc. Thread-pool xử lý các công việc theo thứ tự như khi bạn thêm chúng vào hàng đợi.
• Một khi công việc đã được đặt vào hàng đợi thì bạn không thể hủy hay dừng nó.
Ví dụ dưới đây trình bày cách sử dụng lớp ThreadPool để thực thi một phương thức có tên là DisplayMessage. Ví dụ này sẽ truyền DisplayMessage đến thread-pool hai lần, lần đầu không có đối số, lần sau có đối số là đối tượng MessageInfo (cho phép kiểm soát thông tin mà tiểu trình sẽ hiển thị).
Visual C# Code:
  1. using System;
  2. using System.Threading;
  3.  
  4. // Lớp dùng để truyền dữ liệu cho phương thức DisplayMessage
  5. // khi nó được thực thi bằng thread-pool.
  6. public class MessageInfo {
  7.  
  8.     private int iterations;
  9.     private string message;
  10.  
  11.     // Phương thức khởi dựng nhận các thiết lập cấu hình cho tiểu trình.
  12.     public MessageInfo(int iterations, string message) {
  13.  
  14.         this.iterations = iterations;
  15.         this.message = message;
  16.     }
  17.  
  18.     // Các thuộc tính dùng để lấy các thiết lập cấu hình.
  19.     public int Iterations { get { return iterations; } }
  20.     public string Message { get { return message; } }
  21. }
  22.  
  23. public class ThreadPoolExample {
  24.  
  25.     // Hiển thị thông tin ra cửa sổ Console.
  26.     public static void DisplayMessage(object state) {
  27.  
  28.         // Ép đối số state sang MessageInfo.
  29.         MessageInfo config = state as MessageInfo;
  30.  
  31.         // Nếu đối số config là null, không có đối số nào được
  32.         // truyền cho phương thức ThreadPool.QueueUserWorkItem;
  33.         // sử dụng các giá trị mặc định.
  34.         if (config == null) {
  35.  
  36.             // Hiển thị một thông báo ra cửa sổ Console ba lần.
  37.             for (int count = 0; count < 3; count++) {
  38.  
  39.                 Console.WriteLine("A thread-pool example.");
  40.  
  41.                 // Vào trạng thái chờ, dùng cho mục đích minh họa.
  42.                 // Tránh đưa các tiểu trình của thread-pool
  43.                 // vào trạng thái chờ trong các ứng dụng thực tế.
  44.                 Thread.Sleep(1000);
  45.             }
  46.  
  47.         } else {
  48.  
  49.             // Hiển thị một thông báo được chỉ định trước
  50.             // với số lần cũng được chỉ định trước.
  51.             for (int count = 0; count < config.Iterations; count++) {
  52.  
  53.                 Console.WriteLine(config.Message);
  54.  
  55.                 // Vào trạng thái chờ, dùng cho mục đích minh họa.
  56.                 // Tránh đưa các tiểu trình của thread-pool
  57.                 // vào trạng thái chờ trong các ứng dụng thực tế.
  58.                 Thread.Sleep(1000);
  59.             }
  60.         }
  61.     }
  62.  
  63.     public static void Main() {
  64.  
  65.         // Tạo một đối tượng ủy nhiệm, cho phép chúng ta
  66.         // truyền phương thức DisplayMessage cho thread-pool.
  67.         WaitCallback workMethod =
  68.             new WaitCallback(ThreadPoolExample.DisplayMessage);
  69.  
  70.         // Thực thi DisplayMessage bằng thread-pool (không có đối số).
  71.         ThreadPool.QueueUserWorkItem(workMethod);
  72.  
  73.         // Thực thi DisplayMessage bằng thread-pool (truyền một
  74.         // đối tượng MessageInfo cho phương thức DisplayMessage).
  75.         MessageInfo info =
  76.             new MessageInfo(5, "A thread-pool example with arguments.");
  77.  
  78.         ThreadPool.QueueUserWorkItem(workMethod, info);
  79.  
  80.         // Nhấn Enter để kết thúc.
  81.         Console.WriteLine("Main method complete. Press Enter.");
  82.         Console.ReadLine();
  83.     }
  84. }

Trích từ "Các giải pháp lập trình C#"