2011-12-19 27 views
7

Sau khi đọc tài liệu cho lớp Dispatcher, tôi nhận ra rằng nó có thể được sử dụng cho việc xếp hàng không giao diện người dùng của các hành động.Điều phối viên - Tính năng này hoạt động như thế nào?

Vậy lớp Dispatcher thực sự hoạt động như thế nào? Tôi nhận thức được điều đó, công việc chính của nó là xếp hàng các hành động vào một chủ đề cụ thể - nhưng làm thế nào để "gửi" các hành động đó đến luồng? Và làm thế nào để các chủ đề "có được" những hành động này?

Đoán tốt nhất của tôi là có một số loại "chuỗi chủ đề" cho mỗi chuỗi, nhưng sau đó lại không có ý tưởng.

+0

Bạn có hỏi trong ngữ cảnh của WPF hoặc Silverlight không? –

+0

@ JoeWhite, Không. Bạn có thể sử dụng 'Dispatcher' trong một ứng dụng không phải gui. – ebb

+2

@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. –

Trả lời

2

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.

+0

Cảm ơn bạn đã trả lời! - Tôi hoàn toàn hiểu ý tưởng của nhà sản xuất/người tiêu dùng, vv. Điều tôi đang đặt câu hỏi là tại sao 'Dispatcher' cũng hoạt động trong một ứng dụng không phải gui. Hiện tại, tôi đang xem mã nguồn cho lớp 'Dispatcher' thực sự, và có vẻ như nó tạo ra một" cửa sổ chỉ thông báo ", và do đó cũng là một vòng lặp tin nhắn - nhưng một lần nữa .. Tôi không chắc chắn gì cả . – ebb

0

Câu hỏi rất thú vị, nhưng bạn không cần một cửa sổ để có một hàng đợi thông điệp, đây là những khái niệm riêng biệt, bạn có thể tạo một hàng đợi thông điệp trên bất kỳ chủ đề chỉ bằng cách gọi PeekMessage.

For more information take a look at here

nhưng tất nhiên nó không có nghĩa là một Dispatcher mà không có một cửa sổ là của bất kỳ sử dụng. Tôi có thể giả định rằng các nhà thiết kế đã suy nghĩ về một đối tượng Dispatcher độc lập để cho phép nó xử lý nhiều cửa sổ như ứng dụng có.

Các vấn đề liên quan