Nó có phải là một loại lai của sự vật? (vd )
Về cơ bản là có.
Giả sử chúng ta có
async void MyButton_OnClick() { await Foo(); Bar(); }
async Task Foo() { await Task.Delay(123); Blah(); }
Đây là một lời giải thích cực kỳ đơn giản về cách tiếp tục được thống nhất. Mã thực sự phức tạp hơn đáng kể, nhưng điều này có ý tưởng xuyên suốt.
Bạn bấm vào nút. Một tin nhắn được xếp hàng. Vòng lặp thông báo xử lý tin nhắn và gọi trình xử lý nhấp chuột, đặt địa chỉ trả về của hàng đợi tin nhắn trên ngăn xếp. Đó là, điều xảy ra sau khi xử lý xong là vòng lặp thông báo phải tiếp tục chạy. Vì vậy, sự tiếp tục của xử lý là vòng lặp.
Trình xử lý nhấp chuột gọi Foo (), đặt địa chỉ trả về của chính nó trên ngăn xếp. Đó là, phần tiếp theo của Foo là phần còn lại của trình xử lý nhấp chuột.
Foo gọi Task.Delay, đặt địa chỉ trả về của chính nó trên ngăn xếp.
Task.Delay thực hiện bất kỳ phép thuật nào cần làm để trả lại ngay một Nhiệm vụ. Ngăn xếp được bật lên và chúng tôi trở lại Foo.
Foo kiểm tra tác vụ được trả về để xem nó đã hoàn thành chưa. Không phải vậy. Các sự tiếp nối của chờ đợi là để gọi Blah (), vì vậy Foo tạo ra một đại biểu trong đó kêu gọi Blah (), và dấu hiệu cho thấy ủy lên như việc tiếp tục nhiệm vụ. (Tôi chỉ đưa ra một tuyên bố sai lầm nhỏ; bạn có nắm bắt được không? Nếu không, chúng tôi sẽ tiết lộ ngay lập tức.)
Foo sau đó tạo đối tượng Nhiệm vụ riêng của mình, đánh dấu nó là chưa hoàn thành và trả nó lên ngăn xếp cho trình xử lý nhấp chuột.
Trình xử lý nhấp chuột kiểm tra nhiệm vụ của Foo và phát hiện ra nó chưa hoàn thành. Việc tiếp tục chờ đợi trong trình xử lý là gọi Bar (), vì vậy trình xử lý nhấp chuột tạo ra một ủy nhiệm gọi Bar () và đặt nó làm tiếp tục nhiệm vụ được Foo () trả về. Sau đó, nó trả lại ngăn xếp vào vòng lặp tin nhắn.
Vòng lặp tin nhắn tiếp tục xử lý tin nhắn. Cuối cùng, ma thuật hẹn giờ được tạo bởi tác vụ trì hoãn thực hiện công việc của nó và gửi một thông báo tới hàng đợi nói rằng việc tiếp tục tác vụ trì hoãn có thể được thực thi. Vì vậy, vòng lặp thông báo gọi tiếp tục nhiệm vụ, đặt chính nó vào ngăn xếp như bình thường. Đại biểu đó gọi Blah (). Blah () làm những gì nó làm và trả lại stack.
Bây giờ chuyện gì xảy ra? Đây là một chút khó khăn. Việc tiếp tục nhiệm vụ trì hoãn không chỉ gọi Blah (). Nó cũng phải kích hoạt một cuộc gọi đến Bar () , nhưng nhiệm vụ đó không biết về Bar!
Foo thực sự đã tạo ra một đại biểu mà (1) gọi Blah () và (2) gọi việc tiếp tục nhiệm vụ mà Foo đã tạo và giao lại cho người xử lý sự kiện. Đó là cách chúng tôi gọi một đại biểu gọi Bar ().
Và bây giờ chúng tôi đã làm mọi thứ chúng tôi cần làm, theo đúng thứ tự. Nhưng chúng tôi không bao giờ ngừng xử lý tin nhắn trong vòng lặp tin nhắn trong một thời gian dài, vì vậy ứng dụng vẫn phản hồi.
Rằng các kịch bản này quá tiên tiến cho một ngăn xếp có ý nghĩa hoàn hảo, nhưng điều gì thay thế cho ngăn xếp?
Một biểu đồ của các đối tượng tác vụ chứa các tham chiếu cho nhau thông qua các lớp đóng của các đại biểu. Các lớp đóng cửa đó là các máy trạng thái theo dõi vị trí của việc chờ đợi được thực hiện gần đây nhất và các giá trị của người dân địa phương. Thêm vào đó, trong ví dụ đã cho, một hàng đợi các hành động ở trạng thái toàn cầu được thực thi bởi hệ điều hành và vòng lặp thông báo thực thi các hành động đó.
Bài tập: làm thế nào để bạn cho rằng tất cả điều này hoạt động trong một thế giới không có vòng lặp thông điệp? Ví dụ, các ứng dụng giao diện điều khiển. chờ đợi trong một ứng dụng giao diện điều khiển khá khác nhau; bạn có thể suy luận làm thế nào nó hoạt động từ những gì bạn biết cho đến nay?
Khi tôi đã biết về những năm trước đây, ngăn xếp ở đó vì nó nhanh và nhẹ, một phần bộ nhớ được phân bổ tại ứng dụng cách xa heap vì nó hỗ trợ quản lý hiệu quả cao cho nhiệm vụ trong tay (ý định chơi chữ?). Có gì thay đổi?
Ngăn xếp là một cấu trúc dữ liệu hữu ích khi vòng đời kích hoạt phương thức tạo thành một ngăn xếp, nhưng trong ví dụ của tôi, các kích hoạt của trình xử lý nhấp chuột, Foo, Bar và Blah không tạo thành một ngăn xếp. Và do đó, cấu trúc dữ liệu đại diện cho dòng công việc đó không thể là một ngăn xếp; đúng hơn nó là một biểu đồ của các nhiệm vụ được phân bổ heap và các đại biểu đại diện cho một quy trình công việc. Sự chờ đợi là những điểm trong quy trình làm việc mà tiến trình không thể được thực hiện thêm trong quy trình làm việc cho đến khi công việc bắt đầu sớm hơn đã hoàn thành; trong khi chờ đợi, chúng tôi có thể thực hiện các công việc khác không phụ thuộc vào các nhiệm vụ bắt đầu cụ thể đó đã hoàn thành.
Ngăn xếp chỉ là một mảng các khung, trong đó các khung chứa (1) con trỏ đến giữa các hàm (nơi xảy ra cuộc gọi) và (2) giá trị của các biến và temps cục bộ. Các nhiệm vụ tiếp tục giống nhau: ủy nhiệm là một con trỏ tới hàm và nó có trạng thái tham chiếu một điểm cụ thể ở giữa hàm (trong đó chờ đợi xảy ra) và bao đóng có các trường cho từng biến cục bộ hoặc tạm thời . Các khung không tạo thành một mảng gọn gàng đẹp nữa, nhưng tất cả các thông tin đều giống nhau.