Using Threads 1 Tin trnh Tiu trnh Tin

  • Slides: 40
Download presentation
Using Threads 1

Using Threads 1

Tiến trình & Tiểu trình § Tiến trình là một thể hiện của chương

Tiến trình & Tiểu trình § Tiến trình là một thể hiện của chương trình đang hoạt động. § Một tiến trình luôn sở hữu một không gian địa chỉ chứa mã chương trình, các dữ liệu, sở hữu tài nguyên của hệ thống như tập tin, đối tượng đồng bộ hóa, . . . § Mỗi tiến trình khi mới tạo lập đều chỉ có một tiểu trình chính nhưng sau đó có thể tạo lập nhiều tiến trình khác. § Tiểu trình là một thành phần đơn vị của tiến trình có thể thực hiện các chỉ thị ứng với một đoạn mã nào đó của chương trình. §Hệ điều hành Windows cho phép các tiểu trình họat động độc lập và tổ chức điều phối (lập lịch tiến trình) CPU để các tiểu trình họat động đồng thời. §Hệ điều hành phân chia thời gian sử dụng CPU cho mỗi tiến trình rất mịn theo kiểu xoay vòng. §Mỗi tiểu trình có thể có 1 trong 3 trạng thái: Running, Ready, Blocked. 2

Tiến trình & Tiểu trình T 1 T 8 T 2 Biến toàn cục

Tiến trình & Tiểu trình T 1 T 8 T 2 Biến toàn cục tiến trình Tiểu trình 1 Tiểu trình 2 T 4 Stack tiểu trình 2 CPU T 6 Stack tiểu trình 1 T 7 Biến môi trường tiến trình T 3 Heap của tiến trình T 5 - Hệ thống tốn bộ nhớ để lưu trữ các cấu trúc mô tả tiến trình hay tiểu trình. - Hệ thống tốn thời gian để theo vết chương trình, quản lý các tiểu trình. - Nhiều tiến trình tranh chấp tài nguyên dùng chung đòi hỏi thực hiện đồng bộ hóa. 3

Thread § C# hỗ trợ việc xử lý song thông qua các đa tiểu

Thread § C# hỗ trợ việc xử lý song thông qua các đa tiểu trình. § Một ví dụ về tiểu trình trong C#. using System; using System. Threading; class Thread. Test { static void Main() { Thread t = new Thread (Write. Y); t. Start(); Tạo ủy nhiệm thread Kích hoạt thread t Gọi thread Write // Đồng thời thực hiện trên main thread. for (int i = 0; i < 1000; i++) Console. Write ("x"); } static void Write. Y() { for (int i = 0; i < 1000; i++) Console. Write ("y"); } } 4

Thread Tiểu trình chính tạo ra một tiểu trình mới t và thực thi

Thread Tiểu trình chính tạo ra một tiểu trình mới t và thực thi phương thức Write. Y()để in ra ký tự ‘y’. Song song việc thực hiện tiểu trình này, tiểu trình chính cũng thực hiện việc in ra ký tự ‘x’ 5

Thread § Khi được bắt đầu, thuộc tính Is. Alive của tiểu trình trả

Thread § Khi được bắt đầu, thuộc tính Is. Alive của tiểu trình trả về giá trị true cho tới khi tiểu trình kết thúc. § Khi kết thúc, tiểu trình không thể tự bắt đầu lại. § Mỗi tiểu trình có một vùng nhớ stack riêng để xử lý. static void Main() { new Thread (Go). Start(); Go(); } // Call Go() on a new thread // Call Go() on the main thread static void Go() { // Declare and use a local variable - 'cycles' for (int cycles = 0; cycles < 5; cycles++) Console. Write ('? '); } 6

Thread § Tiểu trình chia sẻ dữ liệu nếu cùng tham chiếu trên một

Thread § Tiểu trình chia sẻ dữ liệu nếu cùng tham chiếu trên một đối tượng. class Thread. Test { bool done = false; static void Main() { Thread. Test tt = new Thread. Test(); new Thread (tt. Go). Start(); tt. Go(); } // Create a common instance // Note that Go is now an instance method void Go() { if (!done) { done = true; Console. Write. Line ("Done"); } } Thực hiện một lần } 7

Thread Để đợi một tiểu trình khác kết thúc bằng cách gọi phương thức

Thread Để đợi một tiểu trình khác kết thúc bằng cách gọi phương thức Join(). static void Main(string[] args) { Thread t 1 = new Thread(Method. A); Thread t 2 = new Thread(Method. B); Thread t 3 = new Thread(Method. C); t 1. Start(); t 2. Join(); t 3. Start(); } static void Method. A() { for (int i = 0; i < 100; i++) Console. Write("0"); } static void Method. B() { for (int i = 0; i < 100; i++) Console. Write("1"); } static void Method. C() { for (int i = 0; i < 100; i++) Console. Write("2");

Thread § Thread. Sleep sẽ dừng tiểu trình hiện hành. // Dừng trong một

Thread § Thread. Sleep sẽ dừng tiểu trình hiện hành. // Dừng trong một giờ Thread. Sleep (Time. Span. From. Hours (1)); //Dừng trong 500 milli giây Thread. Sleep (500); 9

Thread § Thuộc tính Thread. Current. Thread sẽ chỉ ra Thread đang thực thi.

Thread § Thuộc tính Thread. Current. Thread sẽ chỉ ra Thread đang thực thi. § Ví dụ về xác định tên của Thread class Thread. Naming { static void Main() { Tiểu trình tự Thread. Current. Thread. Name = "main"; điều phối và Thread worker = new Thread (Go); thực hiện worker. Name = "worker"; xen kẽ nhau worker. Start(); Tiểu trình con Go(); } Câu lệnh trong tiếu static void Go() trình chính { for (int i = 0; i < 100; i++ ) Console. Write. Line ("Hello from " + Thread. Current. Thread. Name); } } 10

Các phương thức trong lớp Thread Phương thức Mô tả Abort() Thoát khỏi Thread

Các phương thức trong lớp Thread Phương thức Mô tả Abort() Thoát khỏi Thread Equals() So sánh hai đối tượng thread Get. Hash. Code() Lấy giá trị mô tả của thread Get. Type() Lấy ra kiểu thread hiện hành Interrupt() Ngắt một thread trong trạng thái đợi Join() Thực thi việc gọi thread đến khi hết Resume() Thực hiện lại thread đang bị ngưng Start() HĐH sẽ tạo thread sang trạng thái running Suspend() Ngừng lại một thread đang thực thi To. String() Chuyển đối tượng thread thành chuỗi 11

Bài tập 01 - Thread using System; using System. Threading; class Thread. Sample {

Bài tập 01 - Thread using System; using System. Threading; class Thread. Sample { public static void Main() {Thread. Sample ts = new Thread. Sample(); } public Thread. Sample() { int i; Thread new. Counter = new Thread(new Thread. Start(Counter)); Thread new. Counter 2 = new Thread(new Thread. Start(Counter 2)); new. Counter. Start(); new. Counter 2. Start(); for(i = 0; i < 10; i++) { Console. Write. Line("main: {0}", i); Thread. Sleep(1000); } } void Counter() { for (int i = 0; i < 10; i++) { Console. Write. Line(" thread: {0}", i); Thread. Sleep(2000); } } void Counter 2() { for (int i = 0; i < 10; i++) { Console. Write. Line(" thread 2: {0}", i); Thread. Sleep(3000); } } } 12

Thread 13

Thread 13

Tạo tiểu trình trong. NET - Thread Thư viện lớp. NET Framework cung cấp

Tạo tiểu trình trong. NET - Thread Thư viện lớp. NET Framework cung cấp một số phương pháp tạo tiểu trình mới: § Thực thi một phương phức bằng tiểu trình trong Thread-pool. § Thực thi phương thức một cách bất đồng bộ. § Thực thi một phương thức bằng tiểu trình theo chu kỳ hay ở một thời điểm xác định. §Thực thi phương thức bằng cách ra hiệu đối tượng Wait. Handle. 14

Tạo tiểu trình trong Thread-pool § Khai báo một phương thức chứa mã lệnh

Tạo tiểu trình trong Thread-pool § 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ố. § Tạo một thể hiện của ủy nhiệm System. Threading. Wait. Callback tham chiếu đến phương thức này. § Gọi phương thức tĩnh Queue. User. Work. Item của lớp: System. Threading. Thread. Pool. § 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. 15

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example using System; using System.

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example using System; using System. Threading; // Lớp dùng để truyền dữ liệu cho phương thức Display. Message // khi nó được thực thi bằng thread-pool. public class Message. Info { private int iterations; private string message; // Phương thức khởi tạo thiết lập cấu hình cho tiểu trình. public Message. Info(int iterations, string message) { this. iterations = iterations; this. message = message; } // Các thuộc tính dùng để lấy các thiết lập cấu hình. public int Iterations { get { return iterations; } } public string Message { get { return message; } } } 16

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example public class Thread. Pool.

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example public class Thread. Pool. Example { // Hiển thị thông tin ra cửa sổ Console. public static void Display. Message(object state) { // Ép đối số state sang Message. Info config = state as Message. Info; // Nếu đối số config là null, không có đối số nào truyền cho // phương thức Thread. Pool. Queue. User. Work. Item; // sử dụng các giá trị mặc định. if (config == null) { // Hiển thị một thông báo ra cửa sổ Console ba lần. for (int count = 0; count < 3; count++) { Console. Write. Line("A thread-pool example. "); // Vào trạng thái chờ, dùng cho mục đích minh họa. // Tránh đưa các tiểu trình của thread-pool // vào trạng thái chờ trong các ứng dụng thực tế. Thread. Sleep(1000); } } 17

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example else { // Hiển

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example else { // Hiển thị một thông báo được chỉ định trước // với số lần cũng được chỉ định trước. for (int count = 0; count < config. Iterations; count++) { Console. Write. Line(config. Message); // Vào trạng thái chờ, dùng cho mục đích minh họa. // Tránh đưa các tiểu trình của thread-pool // vào trạng thái chờ trong các ứng dụng thực tế. Thread. Sleep(1000); } } } 18

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example public static void Main()

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example public static void Main() { // Tạo một đối tượng ủy nhiệm, cho phép chúng ta // truyền phương thức Display. Message cho thread-pool. Wait. Callback work. Method = new Wait. Callback(Thread. Pool. Example. Display. Message); // Thực thi Display. Message bằng thread-pool (không có đối số). Thread. Pool. Queue. User. Work. Item(work. Method); // Thực thi Display. Message bằng thread-pool (truyền một // đối tượng Message. Info cho phương thức Display. Message). Message. Info info = new Message. Info(5, "A thread-pool example with arguments. "); Thread. Pool. Queue. User. Work. Item(work. Method, info); // Nhấn Enter để kết thúc. Console. Write. Line("Main method complete. Press Enter. "); Console. Read. Line(); } } 19

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example thread có đối số

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example thread có đối số và không đối số thực hiện xen kẽ nhau 20

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example 2 static void Main(string[]

Tạo tiểu trình trong Thread-pool Chương trình Thread. Pool. Example 2 static void Main(string[] args) { Wait. Callback work = new Wait. Callback(Thread. Proc); Thread. Pool. Queue. User. Work. Item(Thread. Proc, 123); Console. Read. Line(); } public static void Thread. Proc(object data) { for (int i = 0; i < 10; i++) { Console. Write. Line("Thread callback: " + data); Thread. Sleep(500); } }

Tạo tiểu trình trong Thread-pool § Khi một tiểu trình (thread) trong thread-pool sẵn

Tạo tiểu trình trong Thread-pool § Khi một tiểu trình (thread) 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, tiểu trình quay về thread-pool và nhận công việc kế tiếp từ hàng đợi. § Sử dụng thread-pool giúp đơn giản hóa việc lập trình hỗ trợ đa tiểu trình. § Cần lưu ý khi quyết định sử dụng thread-pool: • 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. • Đặc biệt, 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. • 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ự thêm chúng vào hàng đợi. 22

Kiểm soát thread § Tạo một đối tượng ủy nhiệm Thread. Start tham chiếu

Kiểm soát thread § Tạo một đối tượng ủy nhiệm Thread. Start tham chiếu đến phương thức chứa mã lệnh mà muốn dùng một tiểu trình mới để thực thi. Phương thức được tham chiếu phải trả về void và không có đối số. § Tạo đối tượng Thread, và truyền thể hiện ủy nhiệm Thread. Start cho phương thức khởi tạo. Tiểu trình mới có trạng thái ban đầu là Unstarted. § Gọi thực thi phương thức Start của đối tượng Thread để chuyển trạng thái của nó sang Thread. State. Running và bắt đầu thực thi phương thức được tham chiếu bởi thể hiện ủy nhiệm Thread. Start. § Ủy nhiệm Thread. Start không có đối số, nên không thể truyền dữ liệu trực tiếp cho phương thức được tham chiếu. Để truyền dữ liệu cho tiểu trình mới, cần phải cấu hình dữ liệu là khả truy xuất đối với mã lệnh đang chạy trong tiểu trình mới. § Cách tiếp cận thông thường là tạo một lớp đóng gói cả dữ liệu cần cho tiểu trình và phương thức được thực thi bởi tiểu trình. Khi muốn chạy một tiểu trình mới, thì tạo một đối tượng của lớp này, cấu hình trạng thái cho nó, và rồi chạy tiểu trình. 23

Kiểm soát thread using System; using System. Threading; public class Thread. Example { //

Kiểm soát thread using System; using System. Threading; public class Thread. Example { // Các biến giữ thông tin trạng thái. private int iterations; private string message; private int delay; public Thread. Example(int iterations, string message, int delay) { this. iterations = iterations; this. message = message; this. delay = delay; } public void Start() { // Tạo một thể hiện ủy nhiệm Thread. Start // tham chiếu đến Display. Message. Thread. Start method = new Thread. Start(this. Display. Message); // Tạo một đối tượng Thread và truyền thể hiện ủy nhiệm // Thread. Start cho phương thức khởi dựng của nó. Thread thread = new Thread(method); Console. Write. Line("{0} : Starting new thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); // Khởi chạy tiểu trình mới. thread. Start(); } 24

Kiểm soát thread private void Display. Message() { // Hiển thị thông báo ra

Kiểm soát thread private void Display. Message() { // Hiển thị thông báo ra cửa sổ Console với số lần // được chỉ định (iterations), nghỉ giữa mỗi thông báo // một khoảng thời gian được chỉ định (delay). for (int count = 0; count < iterations; count++) { Console. Write. Line("{0} : {1}", Date. Time. Now. To. String("HH: mm: ss. ffff"), message); Thread. Sleep(delay); } } 25

Kiểm soát thread public static void Main() { // Tạo một đối tượng Thread.

Kiểm soát thread public static void Main() { // Tạo một đối tượng Thread. Example example = new Thread. Example(5, "A thread example. ", 500); // Khởi chạy đối tượng Thread. Example. example. Start(); // Tiếp tục thực hiện công việc khác. for (int count = 0; count < 13; count++) { Console. Write. Line("{0} : Continue processing. . . ", Date. Time. Now. To. String("HH: mm: ss. ffff")); Thread. Sleep(200); } // Nhấn Enter để kết thúc. Console. Write. Line("Main method complete. Press Enter. "); Console. Read. Line(); } } 26

Kiểm soát thread Bắt đầu thực hiện phương thức Start() trong lớp Thread. Example

Kiểm soát thread Bắt đầu thực hiện phương thức Start() trong lớp Thread. Example Thực hiện tiếu trình Main() Thực hiện tiếu trình Display. Message() 27

Bài tập 02 – Kiểm soát thread using System; using System. Threading; public class

Bài tập 02 – Kiểm soát thread using System; using System. Threading; public class Thread. Control. Example { private static void Display. Message() { // Lặp đi lặp lại việc hiển thị một thông báo ra cửa sổ Console. while (true) { try { Console. Write. Line("{0} : Second thread running. Enter (S)uspend, (R)esume, (I)nterrupt, or (E)xit. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); // Nghỉ 2 giây. Thread. Sleep(2000); } catch (Thread. Interrupted. Exception) { // Tiểu trình đã bị gián đoạn. Việc bắt ngoại lệ // Thread. Interrupted. Exception cho phép ví dụ này // thực hiện hành động phù hợp và tiếp tục thực thi. Console. Write. Line("{0} : Second thread interrupted. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); } 28

Bài tập 02 – Kiểm soát thread catch (Thread. Abort. Exception abort. Ex) {

Bài tập 02 – Kiểm soát thread catch (Thread. Abort. Exception abort. Ex) { // Đối tượng trong thuộc tính // Thread. Abort. Exception. State được cung cấp // bởi tiểu trình đã gọi Thread. Abort. // Trong trường hợp này, nó chứa một chuỗi // mô tả lý do của việc hủy bỏ. Console. Write. Line("{0} : Second thread aborted ({1})", Date. Time. Now. To. String("HH: mm: ss. ffff"), abort. Exception. State); // Mặc dù Thread. Abort. Exception đã được thụ lý, // bộ thực thi sẽ ném nó lần nữa để bảo đảm tiểu trình kết thúc } } } 29

Bài tập 02 – Kiểm soát thread public static void Main() { // Tạo

Bài tập 02 – Kiểm soát thread public static void Main() { // Tạo một đối tượng Thread và truyền cho nó một thể hiện // ủy nhiệm Thread. Start tham chiếu đến Display. Message. Thread thread = new Thread(new Thread. Start(Display. Message)); Console. Write. Line("{0} : Starting second thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); // Khởi chạy tiểu trình thứ hai. thread. Start(); // Lặp và xử lý lệnh do người dùng nhập. char command = ' '; do { string input = Console. Read. Line(); if (input. Length > 0) command = input. To. Upper()[0]; else command = ' '; switch (command) { case 'S': // Tạm hoãn tiểu trình thứ hai. Console. Write. Line("{0} : Suspending second thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); thread. Suspend(); break; 30

Bài tập 02 – Kiểm soát thread case 'R': // Phục hồi tiểu trình

Bài tập 02 – Kiểm soát thread case 'R': // Phục hồi tiểu trình thứ hai. try { Console. Write. Line("{0} : Resuming second thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); thread. Resume(); } catch (Thread. State. Exception) { Console. Write. Line("{0} : Thread wasn't suspended. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); } break; case 'I': // Gián đoạn tiểu trình thứ hai. Console. Write. Line("{0} : Interrupting second thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); thread. Interrupt(); break; 31

Bài tập 02 – Kiểm soát thread case 'E': // Hủy bỏ tiểu trình

Bài tập 02 – Kiểm soát thread case 'E': // Hủy bỏ tiểu trình thứ hai và truyền một đối tượng // trạng thái cho tiểu trình đang bị hủy, // trong trường hợp này là một thông báo. Console. Write. Line("{0} : Aborting second thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); thread. Abort("Terminating example. "); // Đợi tiểu trình thứ hai kết thúc. thread. Join(); break; }//switch }while (command != 'E'); // Nhấn Enter để kết thúc. Console. Write. Line("Main method complete. Press Enter. "); Console. Read. Line(); }//Main }//Class 32

Bài tập 02 – Kiểm soát thread 33

Bài tập 02 – Kiểm soát thread 33

Bài tập 03 – Kiểm soát thread using System; using System. Threading; public class

Bài tập 03 – Kiểm soát thread using System; using System. Threading; public class Thread. Finish. Example { private static void Display. Message() { // Hiển thị một thông báo ra cửa sổ Console 5 lần. for (int count = 0; count < 5; count++) { Console. Write. Line("{0} : Second thread", Date. Time. Now. To. String("HH: mm: ss. ffff")); // Nghỉ 1 giây. Thread. Sleep(1000); } } 34

Bài tập 03 – Kiểm soát thread public static void Main() { // Tạo

Bài tập 03 – Kiểm soát thread public static void Main() { // Tạo một thể hiện ủy nhiệm Thread. Start // tham chiếu đến Display. Message. Thread. Start method = new Thread. Start(Display. Message); // Tạo một đối tượng Thread và truyền thể hiện ủy nhiệm // Thread. Start cho phương thức khởi dựng của nó. Thread thread = new Thread(method); Console. Write. Line("{0} : Starting second thread. ", Date. Time. Now. To. String("HH: mm: ss. ffff")); // Khởi chạy tiểu trình thứ hai. thread. Start(); // Dừng cho đến khi tiểu trình thứ hai kết thúc, // hoặc Join hết hiệu lực sau 3 giây. if (!thread. Join(3000)) { Console. Write. Line("{0} : Join timed out !!", Date. Time. Now. To. String("HH: mm: ss. ffff")); } // Nhấn Enter để kết thúc. Console. Write. Line("Main method complete. Press Enter. "); Console. Read. Line(); } } 35

Bài tập 03 – Kiểm soát thread Tiểu trình chính kết thúc trước 36

Bài tập 03 – Kiểm soát thread Tiểu trình chính kết thúc trước 36

Bài tập 04 – Kiểm soát thread using System; using System. Diagnostics; public class

Bài tập 04 – Kiểm soát thread using System; using System. Diagnostics; public class Start. Process. Example { public static void Main() { // Tạo một đối tượng Process. Start. Info và cấu hình cho nó // với các thông tin cần thiết để chạy tiến trình mới. Process. Start. Info start. Info = new Process. Start. Info(); start. Info. File. Name = "notepad. exe"; start. Info. Arguments = "file. txt"; start. Info. Working. Directory = "C: \Temp"; start. Info. Window. Style = Process. Window. Style. Maximized; start. Info. Error. Dialog = true; // Tạo một đối tượng Process mới. using (Process process = new Process()) { // Gán Process. Start. Info vào Process. process. Start. Info = start. Info; try { // Khởi chạy tiến trình mới. process. Start(); // Đợi tiến trình mới kết thúc trước khi thoát. Console. Write. Line("Waiting 30 seconds for process to finish. "); process. Wait. For. Exit(30000); } 37

Bài tập 04 – Kiểm soát thread catch (Exception ex) { Console. Write. Line("Could

Bài tập 04 – Kiểm soát thread catch (Exception ex) { Console. Write. Line("Could not start process. "); Console. Write. Line(ex); } } // Nhấn Enter để kết thúc. Console. Write. Line("Main method complete. Press Enter. "); Console. Read. Line(); } } 38

Bài tập 05 – Kiểm soát thread using System; using System. Threading; using System.

Bài tập 05 – Kiểm soát thread using System; using System. Threading; using System. Diagnostics; public class Terminate. Process. Example { public static void Main() { // Tạo một Process mới và chạy notepad. exe. using (Process process = Process. Start("notepad. exe")) { // Đợi 5 giây và kết thúc tiến trình Notepad. Thread. Sleep(5000); // Kết thúc tiến trình Notepad. // Gửi một thông điệp đến cửa sổ chính. if (!process. Close. Main. Window()) { // Không gửi được thông điệp. Kết thúc Notepad bằng Kill. process. Kill(); } 39

Bài tập 05 – Kiểm soát thread else { // Thông điệp được gửi

Bài tập 05 – Kiểm soát thread else { // Thông điệp được gửi thành công; đợi 2 giây // để chứng thực việc kết thúc trước khi viện đến Kill. if (!process. Wait. For. Exit(2000)) { process. Kill(); } // Nhấn Enter để kết thúc. Console. Write. Line("Main method complete. Press Enter. "); Console. Read. Line(); } } 40