Nó không phải là một nhiệm vụ tầm thường để có được một sợi để bắt đầu thực thi mã lên một chủ đề khác. Điểm mấu chốt của vấn đề là bạn không thể chỉ đơn giản là nói với bất kỳ chủ đề nào để bắt đầu thực hiện một phương thức sau khi luồng đó đã bắt đầu. Chuỗi đích phải được thiết lập cụ thể để nhận các loại yêu cầu này trước thời hạn.
Mẫu thông thường được sử dụng là người tiêu dùng sản xuất. Chuỗi đích sẽ quay xung quanh một vòng lặp vô hạn đang chờ tin nhắn xuất hiện trong hàng đợi chặn. Hàng đợi được thiết kế để chặn cho đến khi một mục xuất hiện trong hàng đợi, do đó ngăn chặn chuỗi mục tiêu tiêu tốn thời gian CPU không cần thiết. Đây là một cách thực sự đơn giản để có được một luồng để chấp nhận việc tiêm ủy nhiệm thực thi.
public class Example
{
private BlockingCollection<Action> queue = new BlockingCollection<Action>();
public Example()
{
new Thread(
() =>
{
while (true)
{
Action action = queue.Take();
action();
}
}).Start();
}
public void ExecuteAsync(Action action)
{
queue.Add(action);
}
}
Bây giờ, trong trường hợp của một UI thread nó đã có một vòng lặp thông điệp chạy vì vậy lớp Dispatcher
chỉ có thể gửi một thông điệp đặc biệt vào hàng đợi thông điệp có chứa các đại biểu được thực thi. Ở giữa xử lý tất cả các loại sơn, bấm nút, vv thông điệp đặc biệt này sẽ được chọn bởi các chủ đề giao diện người dùng là tốt và nó sẽ bắt đầu thực hiện các đại biểu.
Vậy lớp Dispatcher thực sự hoạt động như thế nào? Tôi biết điều đó, công việc chính của nó là xếp hàng hành động vào một chủ đề cụ thể - nhưng làm thế nào để nó "gửi" những hành động đó đến luồng?
Bằng cách xếp hàng đại biểu vào hàng đợi mà chuỗi mục tiêu giám sát.
Và cách chuỗi "nhận" các hành động này?
Bằng cách chạy vòng lặp vô hạn theo dõi hàng đợi. Hàng đợi thường là một loại đặc biệt được gọi là hàng đợi chặn chặn chuỗi tiêu thụ nếu hàng đợi trống.
Dự đoán tốt nhất của tôi là có một số loại "chuỗi chủ đề" cho mỗi chủ đề , nhưng sau đó lại không có ý tưởng.
Khá gần. Ngoại trừ các chủ đề đó không thực sự có hàng đợi được xây dựng cho mục đích này. Nó phải được thiết lập thủ công. Đó là lý do tại sao chỉ các chủ đề được thiết kế đặc biệt mới có thể chấp nhận phép gán đại biểu. Các chuỗi giao diện người dùng được thiết lập theo cách này bởi vì Application.Run
tạo vòng lặp tin nhắn. Trong ví dụ của tôi, bạn sẽ thấy rằng tôi đã phải sử dụng BlockingCollection
và một vòng lặp vô hạn để làm cho nó hoạt động trên một chuỗi công nhân.
Nguồn
2011-12-19 16:58:31
Bạn có hỏi trong ngữ cảnh của WPF hoặc Silverlight không? –
@ JoeWhite, Không. Bạn có thể sử dụng 'Dispatcher' trong một ứng dụng không phải gui. – ebb
@ebb, bạn có thể sử dụng nó trong một ứng dụng không có GUI, nhưng nó không thực sự có ý nghĩa ... có nhiều công cụ thích hợp hơn để làm điều đó. Điều phối viên * được * thiết kế với các kịch bản giao diện người dùng. –