1. Trang chủ
  2. » Công Nghệ Thông Tin

Các giải pháp lập trình CSharp- P13

10 2 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 2,63 MB

Nội dung

Các giải pháp lập trình CSharp- P13: Các giải pháp lập trình C# khảo sát chiều rộng của thư viện lớp .NET Framework và cung cấp giải pháp cụ thể cho các vấn đề thường gặp. Mỗi giải pháp được trình bày theo dạng “vấn đề/giải pháp” một cách ngắn gọn và kèm theo là các ví dụ mẫu.

121 Chương 4: Tiểu trình, tiến trình, đồng Thực thi phương thức cách bất đồng  Bạn cần thực thi phương thức tiếp tục thực công việc khác phương thức chạy tiểu trình riêng biệt Sau phương thức hoàn tất, bạn cần lấy trị trả  Khai báo ủy nhiệm có chữ ký giống phương thức cần thực thi Sau đó, tạo thể ủy nhiệm tham chiếu đến phương thức Tiếp theo, gọi phương thức BeginInvoke thể ủy nhiệm để thực thi phương thức bạn Kế đến, sử dụng phương thức EndInvoke để kiểm tra trạng thái phương thức thu lấy trị trả hoàn tất Khi cho gọi phương thức, thường thực cách đồng bộ; nghĩa mã lệnh thực lời gọi phải vào trạng thái dừng (block) phương thức thực xong Đây cách cần thiết mã lệnh u cầu q trình thực thi phương thức phải hồn tất trước tiếp tục Tuy nhiên, số trường hợp, bạn lại cần thực thi phương thức cách bất đồng bộ; nghĩa bạn cho thực thi phương thức tiểu trình riêng tiếp tục thực công việc khác .NET Framework hỗ trợ chế độ thực thi bất đồng bộ, cho phép bạn thực thi phương thức cách bất đồng ủy nhiệm Khi khai báo biên dịch ủy nhiệm, trình biên dịch tự động sinh hai phương thức hỗ trợ chế độ thực thi bất đồng bộ: BeginInvoke EndInvoke Khi bạn gọi phương thức BeginInvoke thể ủy nhiệm, phương thức tham chiếu ủy nhiệm xếp vào hàng đợi để thực thi bất đồng Quyền kiểm soát trình thực thi trả cho mã gọi BeginInvoke sau đó, phương thức tham chiếu thực thi ngữ cảnh tiểu trình sẵn sàng trước tiên thread-pool Các đối số phương thức BeginInvoke gồm đối số định ủy nhiệm, cộng với hai đối số dùng phương thức thực thi bất đồng kết thúc Hai đối số là: • Một thể ủy nhiệm System.AsyncCallback tham chiếu đến phương thức mà thực thi gọi phương thức thực thi bất đồng kết thúc Phương thức thực thi ngữ cảnh tiểu trình thread-pool Truyền giá trị null cho đối số nghĩa khơng có phương thức gọi bạn phải sử dụng chế khác để xác định phương thức thực thi bất kết thúc (sẽ thảo luận bên dưới) • Một tham chiếu đối tượng mà thực thi liên kết với trình thực thi bất đồng Phương thức thực thi bất đồng sử dụng hay truy xuất đến đối tượng này, mã lệnh bạn sử dụng phương thức kết thúc, cho phép bạn liên kết thơng tin trạng thái với q trình thực thi bất đồng Ví dụ, đối tượng cho phép bạn ánh xạ kết với thao tác bất đồng khởi tạo trường hợp bạn khởi tạo nhiều thao tác bất đồng sử dụng chung phương thức callback để xử lý việc kết thúc Phương thức EndInvoke cho phép bạn lấy trị trả phương thức thực thi bất đồng bộ, trước hết bạn phải xác định kết thúc Dưới bốn kỹ thuật dùng để xác định phương thức thực thi bất đồng kết thúc hay chưa: 122 Chương 4: Tiểu trình, tiến trình, đồng • Blocking—dừng trình thực thi tiểu trình hành phương thức thực thi bất đồng kết thúc Điều giống với thực thi đồng Tuy nhiên, linh hoạt chọn thời điểm xác để đưa mã lệnh bạn vào trạng thái dừng (block) bạn cịn hội thực thêm số việc trước mã lệnh vào trạng thái • Polling—lặp lặp lại việc kiểm tra trạng thái phương thức thực thi bất đồng để xác định kết thúc hay chưa Đây kỹ thuật đơn giản, xet măt xư ly thi không đươc hiêu qua Bạn nên tránh vịng lặp chặt làm lãng phí thời gian xử lý; tốt nên đặt tiểu trình thực polling vào trạng thái nghỉ (sleep) khoảng thời gian cách sử dụng Thread.Sleep lần kiểm tra trạng thái Bởi ky thuât polling đoi hoi bạn phai tri môt vong lăp nên hoạt đơng cua tiểu trình chơ se bi giới hạn, nhiên bạn co thê dễ dàng câp nhât tiến cơng viêc • Waiting—sử dụng đối tượng dẫn xuất từ lớp System.Threading.WaitHandle để báo hiệu phương thức thực thi bất đồng kết thúc Waiting cải tiến kỹ thuật polling, cho phép bạn chờ nhiều phương thức thực thi bất đồng kết thúc Bạn định giá trị time-out cho phép tiểu trình thực waiting dừng lại phương thức thực thi bất đồng diễn lâu, bạn muốn cập nhật định kỳ trạng thái • Callbacks—Callback phương thức mà thực thi gọi phương thức thực thi bất đồng kết thúc Mã lệnh thực lời gọi không cần thực thao tác kiểm tra nào, tiếp tục thực công việc khác Callback linh hoạt phức tạp, đặc biệt có nhiều phương thức thực thi bất đồng chạy đồng thời sử dụng callback Trong trường hợp thế, bạn phải sử dụng đối tượng trạng thái thích hợp để so trùng phương thức hoàn tất với phương thức khởi tạo Lớp AsyncExecutionExample ví dụ mơ tả chế thực thi bất đồng Nó sử dụng ủy nhiệm có tên AsyncExampleDelegate để thực thi bất đồng phương thức có tên LongRunningMethod Phương thức LongRunningMethod sử dụng Thread.Sleep để mô phương thức có thời gian thực thi dài // Ủy nhiệm cho phép bạn thực việc thực thi bất đồng // AsyncExecutionExample.LongRunningMethod public delegate DateTime AsyncExampleDelegate(int delay, string name); // Phương thức có thời gian thực thi dài public static DateTime LongRunningMethod(int delay, string name) { Console.WriteLine("{0} : {1} example - thread starting.", DateTime.Now.ToString("HH:mm:ss.ffff"), name); 123 Chương 4: Tiểu trình, tiến trình, đồng // Mơ việc xử lý tốn nhiều thời gian Thread.Sleep(delay); Console.WriteLine("{0} : {1} example - thread finishing.", DateTime.Now.ToString("HH:mm:ss.ffff"), name); // Trả thời gian hoàn tất phương thức return DateTime.Now; } AsyncExecutionExample chứa năm phương thức diễn đạt cách tiếp cận khác việc kết thúc phương thức thực thi bất đồng Dưới mô tả cung cấp mã lệnh cho phương thức Phương thức BlockingExample Phương thức BlockingExample thực thi bất đồng phương thức LongRunningMethod tiếp tục thực công việc khoảng thời gian Khi xử lý xong công việc này, BlockingExample chuyển sang trang thái dừng (block) phương thức LongRunningMethod kết thúc Để vào trạng thái dừng, BlockingExample thực thi phương thức EndInvoke thể ủy nhiệm AnsyncExampleDelegate Nếu phương thức LongRunningMethod kết thúc, EndInvoke trả lập tức, không, BlockingExample chuyển sang trạng thái dừng phương thức LongRunningMethod kết thúc public static void BlockingExample() { Console.WriteLine(Environment.NewLine + "*** Running Blocking Example ***"); // Gọi LongRunningMethod cách bất đồng Truyền null cho // ủy nhiệm callback đối tượng trạng thái bất đồng AsyncExampleDelegate longRunningMethod = new AsyncExampleDelegate(LongRunningMethod); IAsyncResult asyncResult = longRunningMethod.BeginInvoke(2000, "Blocking", null, null); // Thực công việc khác // sẵn sàng vào trạng thái dừng for (int count = 0; count < 3; count++) { Console.WriteLine("{0} : Continue processing until " + "ready to block ", 124 Chương 4: Tiểu trình, tiến trình, đồng DateTime.Now.ToString("HH:mm:ss.ffff")); Thread.Sleep(200); } // Đi vào trạng thái dừng phương thức // thực thi bất đồng kết thúc thu lấy kết Console.WriteLine("{0} : Blocking until method is " + "complete ", DateTime.Now.ToString("HH:mm:ss.ffff")); DateTime completion = longRunningMethod.EndInvoke(asyncResult); // Hiển thị thông tin kết thúc Console.WriteLine("{0} : Blocking example complete.", completion.ToString("HH:mm:ss.ffff")); } Phương thức PollingExample Phương thức PollingExample thực thi bất đồng phương thức LongRunningMethod sau thực vịng lặp polling LongRunningMethod kết thúc PollingExample kiểm tra thuộc tính IsComplete thể IAsyncResult (được trả BeginInvoke) để xác định phương thức LongRunningMethod kết thúc hay chưa, chưa, PollingExample gọi Thread.Sleep public static void PollingExample() { Console.WriteLine(Environment.NewLine + "*** Running Polling Example ***"); // Gọi LongRunningMethod cách bất đồng Truyền null cho // ủy nhiệm callback đối tượng trạng thái bất đồng AsyncExampleDelegate longRunningMethod = new AsyncExampleDelegate(LongRunningMethod); IAsyncResult asyncResult = longRunningMethod.BeginInvoke(2000, "Polling", null, null); // Thực polling để kiểm tra phương thức thực thi // bất đồng kết thúc hay chưa Nếu chưa kết thúc 125 Chương 4: Tiểu trình, tiến trình, đồng // vào trạng thái chờ 300 mini-giây // trước thực polling lần Console.WriteLine("{0} : Poll repeatedly until method is " + "complete ", DateTime.Now.ToString("HH:mm:ss.ffff")); while(!asyncResult.IsCompleted) { Console.WriteLine("{0} : Polling ", DateTime.Now.ToString("HH:mm:ss.ffff")); Thread.Sleep(300); } // Thu lấy kết phương thức thực thi bất đồng DateTime completion = longRunningMethod.EndInvoke(asyncResult); // Hiển thị thông tin kết thúc Console.WriteLine("{0} : Polling example complete.", completion.ToString("HH:mm:ss.ffff")); } Phương thức WaitingExample Phương thức WaitingExample thực thi bất đồng phương thức LongRunningExample sau chờ LongRunningMethod kết thúc WaitingExample sử dụng thuộc tính AsyncWaitHandle thể IAsyncResult (được trả BeginInvoke) để có WaitHandle sau gọi phương thức WaitOne WaitHandle Việc sử dụng giá trị time-out cho phép WaitingExample dừng trình đợi để thực cơng việc khác dừng hồn tồn phương thức thực thi bất đồng diễn lâu public static void WaitingExample() { Console.WriteLine(Environment.NewLine + "*** Running Waiting Example ***"); // Gọi LongRunningMethod cách bất đồng Truyền null cho // ủy nhiệm callback đối tượng trạng thái bất đồng AsyncExampleDelegate longRunningMethod = new AsyncExampleDelegate(LongRunningMethod); IAsyncResult asyncResult = longRunningMethod.BeginInvoke(2000, "Waiting", null, null); 126 Chương 4: Tiểu trình, tiến trình, đồng // Đợi phương thức thực thi bất đồng kết thúc // Time-out sau 300 mili-giây hiển thị trạng thái // cửa sổ Console trước tiếp tục đợi Console.WriteLine("{0} : Waiting until method is complete ", DateTime.Now.ToString("HH:mm:ss.ffff")); while(!asyncResult.AsyncWaitHandle.WaitOne(300, false)) { Console.WriteLine("{0} : Wait timeout ", DateTime.Now.ToString("HH:mm:ss.ffff")); } // Thu lấy kết phương thức thực thi bất đồng DateTime completion = longRunningMethod.EndInvoke(asyncResult); // Hiển thị thông tin kết thúc Console.WriteLine("{0} : Waiting example complete.", completion.ToString("HH:mm:ss.ffff")); } Phương thức WaitAllExample Phương thức WaitAllExample thực thi bất đồng phương thức LongRunningMethod nhiều lần sau sử dụng mảng đối tượng WaitHandle để đợi tất phương thức kết thúc public static void WaitAllExample() { Console.WriteLine(Environment.NewLine + "*** Running WaitAll Example ***"); // Một ArrayList chứa thể IAsyncResult // cho phương thức thực thi bất đồng ArrayList asyncResults = new ArrayList(3); // Gọi ba lần LongRunningMethod cách bất đồng // Truyền null cho ủy nhiệm callback đối tượng // trạng thái bất đồng Thêm thể IAsyncResult // cho phương thức vào ArrayList AsyncExampleDelegate longRunningMethod = 127 Chương 4: Tiểu trình, tiến trình, đồng new AsyncExampleDelegate(LongRunningMethod); asyncResults.Add(longRunningMethod.BeginInvoke(3000, "WaitAll 1", null, null)); asyncResults.Add(longRunningMethod.BeginInvoke(2500, "WaitAll 2", null, null)); asyncResults.Add(longRunningMethod.BeginInvoke(1500, "WaitAll 3", null, null)); // Tạo mảng đối tượng WaitHandle, // sử dụng để đợi tất phương thức // thực thi bất đồng kết thúc WaitHandle[] waitHandles = new WaitHandle[3]; for (int count = 0; count < 3; count++) { waitHandles[count] = ((IAsyncResult)asyncResults[count]).AsyncWaitHandle; } // Đợi ba phương thức thực thi bất đồng kết thúc // Time-out sau 300 mili-giây hiển thị trạng thái // cửa sổ Console trước tiếp tục đợi Console.WriteLine("{0} : Waiting until all methods are " + "complete ", DateTime.Now.ToString("HH:mm:ss.ffff")); while(!WaitHandle.WaitAll(waitHandles, 300, false)) { Console.WriteLine("{0} : WaitAll timeout ", DateTime.Now.ToString("HH:mm:ss.ffff")); } // Kiểm tra kết phương thức xác định // thời gian phương thức cuối kết thúc DateTime completion = DateTime.MinValue; foreach (IAsyncResult result in asyncResults) { 128 Chương 4: Tiểu trình, tiến trình, đồng DateTime time = longRunningMethod.EndInvoke(result); if ( time > completion) completion = time; } // Hiển thị thông tin kết thúc Console.WriteLine("{0} : WaitAll example complete.", completion.ToString("HH:mm:ss.ffff")); } Phương thức CallbackExample Phương thức CallbackExample thực thi bất đồng phương thức LongRunningMethod truyền thể ủy nhiệm AsyncCallback (tham chiếu đến phương thức CallbackHandler) cho phương thức BeginInvoke Phương thức CallbackHandler gọi cách tự động phương thức LongRunningMethod kết thúc, kết phương thức CallbackExample tiếp tục thực công việc public static void CallbackExample() { Console.WriteLine(Environment.NewLine + "*** Running Callback Example ***"); // Gọi LongRunningMethod cách bất đồng Truyền // thể ủy nhiệm AsyncCallback tham chiếu đến // phương thức CallbackHandler CallbackHandler // tự động gọi phương thức thực thi bất đồng // kết thúc Truyền tham chiếu đến thể ủy nhiệm // AsyncExampleDelegate trạng thái bất đồng bộ; // không, phương thức callback truy xuất // thể ủy nhiệm để gọi EndInvoke AsyncExampleDelegate longRunningMethod = new AsyncExampleDelegate(LongRunningMethod); IAsyncResult asyncResult = longRunningMethod.BeginInvoke(2000, "Callback", new AsyncCallback(CallbackHandler), longRunningMethod); // Tiếp tục với công việc khác for (int count = 0; count < 15; count++) { 129 Chương 4: Tiểu trình, tiến trình, đồng Console.WriteLine("{0} : Continue processing ", DateTime.Now.ToString("HH:mm:ss.ffff")); Thread.Sleep(200); } } // Phương thức xử lý việc kết thúc bất đồng callbacks public static void CallbackHandler(IAsyncResult result) { // Trích tham chiếu đến thể AsyncExampleDelegate // từ thể IAsyncResult AsyncExampleDelegate longRunningMethod = (AsyncExampleDelegate)result.AsyncState; // Thu lấy kết phương thức thực thi bất đồng DateTime completion = longRunningMethod.EndInvoke(result); // Hiển thị thông tin kết thúc Console.WriteLine("{0} : Callback example complete.", completion.ToString("HH:mm:ss.ffff")); } Thực thi phương thức Timer  Bạn cần thực thi phương thức tiểu trình riêng theo chu kỳ hay thời điểm xác định  Khai báo phương thức trả void nhận đối tượng làm đối số Sau đó, tạo thể ủy nhiệm System.Threading.TimerCallback tham chiếu đến phương thức Tiếp theo, tạo đối tượng System.Threading.Timer truyền cho thể ủy nhiệm TimerCallback với đối tượng trạng thái mà Timer truyền cho phương thức bạn Timer hết hiệu lực Bộ thực thi chờ Timer hết hiệu lực sau gọi phương thức bạn tiểu trình thread-pool Thơng thường, hữu ích thực thi phương thức thời điểm xác định hay thời khoảng xác định Ví dụ, bạn cần lưu liệu lúc 1:00 AM ngày hay xóa vùng đệm liệu 20 phút Lớp Timer giúp việc định thời thực thi phương thức trở nên dễ dàng, cho phép bạn thực thi phương thức tham chiếu ủy nhiệm TimerCallback thời khoảng định Phương thức tham chiếu thực thi ngữ cảnh tiểu trình thread-pool 130 Chương 4: Tiểu trình, tiến trình, đồng Khi tạo đối tượng Timer, bạn cần định hai thời khoảng (thời khoảng định giá trị kiểu int, long, uint, hay System.TimeSpan): • Giá trị thời gian trễ (tính mili-giây) để phương thức bạn thực thi lần Chỉ định giá trị để thực thi phương thức lập tức, định System.Threading.Timeout.Infinite để tạo Timer trạng thái chưa bắt đầu (unstarted) • Giá trị thứ hai khoảng thời gian mà Timer lặp lại việc gọi phương thức bạn sau lần thực thi Nếu bạn định giá trị hay Timeout.Infinite Timer thực thi phương thức lần (với điều kiện thời gian trễ ban đầu Timeout.Infinite) Đối số thứ hai cung cấp trị kiểu int, long, uint, hay System.TimeSpan Sau tạo đối tượng Timer, bạn thay đổi thời khoảng sử dụng Timer phương thức Change, bạn thay đổi phương thức gọi Khi dùng xong Timer, bạn nên gọi phương thức Timer.Depose để giải phóng tài nguyên hệ thống bị chiếm giữ Timer Việc hủy Timer hủy phương thức định thời thực thi Lớp TimerExample trình bày cách sử dụng Timer để gọi phương thức có tên TimerHandler Ban đầu, Timer cấu hình để gọi TimerHandler sau hai giây lặp lại sau giây Ví dụ trình bày cách sử dụng phương thức Timer.Change để thay đổi thời khoảng using System; using System.Threading; public class TimerExample { // Phương thức thực Timer hết hiệu lực // Hiển thị thông báo cửa sổ Console private static void TimerHandler(object state) { Console.WriteLine("{0} : {1}", DateTime.Now.ToString("HH:mm:ss.ffff"), state); } public static void Main() { // Tạo thể ủy nhiệm TimerCallback // tham chiếu đến phương thức tĩnh TimerHandler // TimerHandler gọi Timer hết hiệu lực ...122 Chương 4: Tiểu trình, tiến trình, đồng • Blocking—dừng q trình thực thi tiểu trình hành phương thức thực thi bất đồng kết thúc Điều giống với... TimerCallback thời khoảng định Phương thức tham chiếu thực thi ngữ cảnh tiểu trình thread-pool 130 Chương 4: Tiểu trình, tiến trình, đồng Khi tạo đối tượng Timer, bạn cần định hai thời khoảng (thời... gọi phương thức Timer.Depose để giải phóng tài nguyên hệ thống bị chiếm giữ Timer Việc hủy Timer hủy phương thức định thời thực thi Lớp TimerExample trình bày cách sử dụng Timer để gọi phương

Ngày đăng: 20/05/2021, 02:08