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

Tuan12 multithreading, task, async

16 2 0

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Lập trình Windows 11/18/2019 1 Multithread, Asynchronous Programing Lập trình Ứng dụng quản lý Nội dung  Callback function  Khái niệm MultiThread  Asynchronous Programing 11/18/2019 2 Nội dung  Ca[.]

11/18/2019 Lập trình Ứng dụng quản lý Multithread, Asynchronous Programing Nội dung  Callback function  Khái niệm MultiThread  Asynchronous Programing 11/18/2019 Nội dung  Callback function  Khái niệm MultiThread  Asynchronous Programing Khái niệm Callback function  Trong lập trình máy tính, callback đoạn code chạy (thường hàm A) sử dụng tham số truyền vào hàm B Tới thời điểm đó, Hàm A hàm B gọi lại (callback) Các ngôn ngữ lập trình khác hỗ trợ callback theo cách khác nhau, thường triển khai dạng chương trình con, hàm nặc danh, chuỗi lệnh trỏ hàm 11/18/2019 Callback NET  Trong NET sử dụng delegate để thực callback  Ví dụ: static void FindPrimes(int min, Action callback) { for (int i = min; i < int.MaxValue; i++) { // kiểm tra i có phải Prime ko? callback(i); } }  Event chất callback Nội dung  Callback function  Khái niệm MultiThread  Asynchronous Programing 11/18/2019 Multithreading  Máy tính ngày thực đa nhiệm, đa tác vụ đồng thời dựa vào khái niệm Process Thread  Process (tiến trình) hiểu thể (instance) chương trình máy tính thực thi, dựa hệ điều hành, hoàn toàn độc lập với tiến trình khác  Thread nhóm lệnh tạo để thực thi tác vụ process, chúng chia sẻ chung liệu với để xử lý, điều cần thiết nguyên nhân dễ gây lỗi không xử lý cách Ngữ cảnh sử dụng  Tương tác với giao diện tác vụ ngầm chạy  Lướt web Chrome đồng bookmark  Thiết lập độ ưu tiên  Hoạt động tiêu tốn nhiều thời gian khơng dừng tồn ứng dụng  Copy file dung lượng lớn!  Import file vào CSDL … 11/18/2019 Namespace System.Threading  Cung cấp lớp giao diện cho lập trình đa luồng  Class chính: Thread  CurrentThread  IsAlive  IsBackground  Name  Priority  ThreadState Tạo Thread  Tạo phương thức (gọi phương thức callback) thực thi thread gọi  Phương thức phải khơng có tham số có tham số kiểu object kiểu trả void  Bước bỏ qua ta sử dụng anonymous method lambda expression để tạo đoạn mã lệnh thực thi in-line với lệnh khởi tạo thread  Tạo đối tượng Thread truyền delegate ThreadStart chứa phương thức thực thi vào constructor Thread  Chạy thread: Gọi phương thức Start() đối tượng thread vừa tạo 11/18/2019  Ví dụ static void Main(string[] args) { Thread t1 = new Thread(new ThreadStart(MethodA)); Thread t2 = new Thread(new ThreadStart(MethodB)); t1.Start(); t2.Start(); } static void MethodA() { for (int i = 0; i < 100; ++i) Console.Write("A"); } static void MethodB() { for (int i = 0; i < 100; ++i) Console.Write("B"); }  Sử dụng lambda expression static void Main(string[] args) { Thread t1 = new Thread(() => { for (int i = 0; i < 100; ++i) Console.Write("A"); }); Thread t2 = new Thread(() => { for (int i = 0; i < 100; ++i) Console.Write("B"); }); t1.Start(); t2.Start(); } 11/18/2019 Truyền tham số cho Thread  ParameteriedThreadStart giải pháp thay cho ThreadStart trường hợp cần truyền tham số cho thread  Đối tượng delegate ParameteriedThreadStart chấp nhận tham số kiểu object, phương thức callback cần phải ép kiểu để sử dụng kiểu liệu tham số  Ví dụ static void Main(string[] args) { Thread t1 = new Thread(new ParameterizedThreadStart(Method)); Thread t2 = new Thread(new ParameterizedThreadStart(Method)); t1.Start("A"); t2.Start("B"); } static void Method(object param) { string str = (string)param; for (int i = 0; i < 100; ++i) Console.Write(str); } 11/18/2019  Sử dụng lambda expression static void Main(string[] args) { Thread t1 = new Thread((param) => { string str = (string)param; for (int i = 0; i < 100; ++i) Console.Write(str); }); Thread t2 = new Thread((param) => { string str = (string)param; for (int i = 0; i < 100; ++i) Console.Write(str); }); t1.Start("A"); t2.Start("B"); } Property quan trọng Thread  ThreadState cho thấy trạng thái thread Mỗi lời gọi phương thức thread làm thay đổi giá trị thuộc tính Unstarted, Running, Suspended, Stopped, Aborted,…  ThreadPriority xác định mức độ ưu tiên mà thread thực thi so với thread khác Mỗi thread tạo mang giá trị priority Normal Các giá trị mà thuộc tính có bao gồm: Lowest, BelowNormal, Normal, AboveNormal Highest 11/18/2019 Các phương thức thông dụng Thread  Abort(): phương thức gọi, hệ thống ném ngoại lệ ThreadAbortException để kết thúc thread Sau gọi phương thức này, thuộc tính ThreadState chuyển sang giá trị Stopped  Suspend(): phương thức tạm dừng việc thực thi Thread vô thời hạn yêu cầu chạy tiếp tục với phương thức Resume() Tuy nhiên hai phương thức gắn attribute Obsolete để khuyến cáo ta nên sử dụng phương pháp khác để thay  Sleep(): để dừng thread khoảng thời gian tính milisecond, thread chuyển sang trạng thái WaitSleepJoin Chú ý phương thức static khơng cần tạo đối tượng Thread gọi nó, ví dụ: Thread.Sleep(1000) Tùy vào ngữ cảnh gọi Thread.Sleep(), mà Thread thực thi dòng lệnh bị ảnh hưởng  Join(): phương thức hữu ích trường hợp cần thực tác vụ sau thread kết thúc Phương thức dùng sau chạy Thread Các tác vụ nằm phía lệnh gọi Join() Thread thực thi sau Thread hồn tất cơng việc 11/18/2019  Ví dụ static void Main(string[] args) { Thread t1 = new Thread(new ParameterizedThreadStart(Method)); Thread t2 = new Thread(new ParameterizedThreadStart(Method)); Thread t3 = new Thread(new ParameterizedThreadStart(Method)); t1.Start(new object[] { "A", }); t2.Start(new object[] { "B", 100 }); t2.Join(); t3.Start(new object[] { "C", }); } static void Method(object param) { object[] arrObj = (object[])param; string str = (string)arrObj[0]; int n = (int)arrObj[1]; Thread.Sleep(n); for (int i = 0; i < 100; ++i) Console.Write(str); } Kết C xuất sau B dù có làm chậm Thread Foreground Background Thread  Foreground Thread Thread thực thi kết thúc chương trình (Thread chính) hồn thành (hoặc bị bắt buộc ngừng) kết thúc  Background Thread bị khai tử chương trình kết thúc  Mặc định Thread tạo Foreground Thuộc tính để set Foreground hay Background IsBackground 10 11/18/2019  Ví dụ static void Main(string[] args) { Thread t1 = new Thread(() => { Thread.Sleep(1000); Console.WriteLine("Thread running "); }); Thread t2 = new Thread(() => { Thread.Sleep(1200); Console.WriteLine("Thread running "); }); t1.Start(); t2.IsBackground = true; t2.Start(); Console.WriteLine("Main ended "); } Thread Pooling  Thread Pooling kĩ thuật cho phép sử dụng thread hiệu cách quản lý phân phối chúng hợp lý, tận dụng tối đa thời gian nhàn rỗi tăng hiệu suất chương trình  Thread Pooling kĩ thuật áp dụng phổ biến ứng dụng I/O bất đồng tập tin truyền tải liệu mạng  Một đặc điểm Thread pool thread đặt chế độ background (Background Thread)  Để sử dụng thread pool đơn giản sử dụng phương thức tĩnh QueueUserWorkItem() lớp ThreadPool 11 11/18/2019  Ví dụ static void Main(string[] args) { ThreadPool.QueueUserWorkItem(funcWait, "A"); ThreadPool.QueueUserWorkItem(funcWait, "B"); Thread.Sleep(6000); } static void funcWait(object param) { string str = (string) param; for (int i = 0; i < 10; ++i) { Console.WriteLine("{0} running ", str); Thread.Sleep(500); } } Các vấn đề đụng độ Vấn đề nảy sinh Thread truy cập đến đối tượng, trạng thái chia sẻ bất đồng  Ví dụ chương trình sau  static int n = 0; static void Main(string[] args) { Thread t1 = new Thread(() => { for (int i = 0; i < 100; ++i){ n++; if (n > 0){ Thread.Sleep(2); Console.Write("{0}\t", n); } } }); Thread t2 = new Thread(() => { for (int i = 0; i < 100; ++i){ Thread.Sleep(1); n ; } }); t1.Start(); t2.Start(); } 12 11/18/2019 Giải vấn đề đồng  Net cung cấp số kĩ thuật để đồng việc truy xuất liệu Một sử dụng, liệu bị khóa lại thread khác muốn sử dụng phải chờ liệu hay tài nguyên giải phóng  Cụ thể phương pháp cung cấp là: Monitor, SpinLock, Mutex (Mutual exclusive), Semaphore, WaitHandle,  Đơn giản sử dụng Lock  Ví dụ static int n = 0; static object syncObj = new object(); static void Main(string[] args) { Thread t1 = new Thread(() => { for (int i = 0; i < 100; ++i){ lock (syncObj){ n++; if (n > 0){ Thread.Sleep(2); Console.Write("{0}\t", n); } } } }); Thread t2 = new Thread(() => { for (int i = 0; i < 100; ++i){ lock (syncObj){ Thread.Sleep(1); n ; } } }); t1.Start(); t2.Start(); } 13 11/18/2019 Deadlock  Đồng hóa sử dụng thread công việc cần thiết, nhiên không cẩn thận gặp phải tình trạng chương trình dừng hoạt động vơ thời hạn Tình trạng đặt tên Deadlock  Deadlock xảy có hai thread đợi thread giải phóng, thật “trùng hợp” hai lại giữ “chìa khóa”  Ví dụ static int m = 0, n = 0; static object syncM = new object(); static object syncN = new object(); static void Main(string[] args) { Thread t1 = new Thread(() => { lock (syncM){ m++; Thread.Sleep(100); Console.WriteLine("t1 holding m"); lock(syncN){ n ; Console.WriteLine("t1 holding n"); } } }); Thread t2 = new Thread(() => { lock (syncN) { n++; Thread.Sleep(100); Console.WriteLine("t2 holding n"); lock (syncM) { m ; Console.WriteLine("t2 holding m"); } } }); t1.Start(); t2.Start(); } 14 11/18/2019 Nội dung  Callback function  Khái niệm MultiThread  Asynchronous Programing Asynchronous Programing  Là chế xử lý đồng thời nhiều request thread khác đợi kết từ tác vụ tiêu tốn tài nguyên lớn I/O, access database,…  Lợi ích đạt là:  Trải nghiệm người dùng (usability)  Hiệu (performance) 15 11/18/2019 BeginInvoke EndInvoke  Delegate NET có phương thức giúp thực Asynchronous Programing là:  BeginInvoke (args, AsyncCallback, @object) trả IAsyncResult: tự động tạo thread thực tác vụ thread  EndInvoke (IAsyncResult) trả kết tác vụ thực delegate Task, Async, Await  Từ NET 4.5 đưa framework để thực Asynchronous Programing  Một phương thức để thực thi asynchronous cần sử dụng kiểu trả Task  Ví dụ Task taskGetNumber() { return Task.Run(() => { // tác vụ tiêu tốn nhiều thời gian return 1; }); } async void DoIt() { int num = await taskGetNumber(); // thực việc khác chờ kết } 16

Ngày đăng: 09/04/2023, 06:29

Xem thêm:

w