ứng dụng của bạn có một thread UI chính (thường là ManagedThreadId==1
). Thông thường trong một ứng dụng trò chuyện, các sự kiện của bạn sẽ xuất hiện trên các chủ đề khác (hoặc các chủ đề lắng nghe socket chuyên dụng hoặc luồng chủ đề luồng từ mã nghe). Nếu bạn muốn cập nhật giao diện người dùng từ một sự kiện được kéo trên một số chủ đề khác, bạn phải sử dụng bộ điều phối. Một thử nghiệm hữu ích ở đây là phương thức Dispatcher.CheckAccess()
trả về true nếu mã là trên chuỗi giao diện người dùng và sai nếu trên một số luồng khác. Một cuộc gọi thông thường trông giống như sau:
using System.Windows.Threading; // For Dispatcher.
if (Application.Current.Dispatcher.CheckAccess()) {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}
else {
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}));
}
Nếu bạn đang ở trong cửa sổ chính, bạn có thể sử dụng:
Dispatcher.BeginInvoke(...
Nếu bạn đang ở someother bối cảnh ví dụ như một mô hình điểm sau đó sử dụng:
Application.Current.Dispatcher.BeginInvoke(
Gọi vs BeginInvoke
Sử dụng Invoke
nếu bạn muốn xử lí hiện tại để chờ đợi cho đến khi thread UI đã xử lý mã công văn hoặc BeginInvoke
nếu bạn muốn chuỗi hiện tại tiếp tục mà không cần đợi thao tác hoàn tất trên chuỗi giao diện người dùng.
MessageBox, Dispatchers và Invoke/BeginInvoke:
Dispatcher.Invoke
sẽ chặn thread của bạn cho đến khi MessageBox được sa thải.
Dispatcher.BeginInvoke
sẽ cho phép mã chuỗi của bạn tiếp tục thực thi trong khi chuỗi giao diện người dùng sẽ chặn trên cuộc gọi MessageBox cho đến khi được loại bỏ.
CurrentDispatcher vs Current.Dispatcher!
Hãy là sản phẩm của Dispatcher.CurrentDispatcher
vì sự hiểu biết của tôi về điều này là sẽ trả về Bộ điều phối cho chuỗi hiện tại chứ không phải là chuỗi giao diện người dùng. Nói chung, bạn quan tâm đến người điều phối trên luồng giao diện người dùng - Application.Current.Dispatcher
luôn trả về điều này.
lưu ý khác:
Nếu bạn đang tìm kiếm bạn đang phải rà soát điều phối CheckAccess thường sau đó một phương pháp helper hữu ích là:
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
Mà có thể được gọi là:
DispatchIfNecessary(() => {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});
Đó phụ thuộc ... Trên phương thức nào mà phương thức đó chạy? Ngoài ra, chỉ để chắc chắn, bạn đang sử dụng WPF, phải không? ('Dispatcher' chỉ làm việc với điều đó.) – svick
Bạn đang sử dụng khung UI nào?(WinForms, WPF, hoặc SL) Có sự khác biệt giữa chúng –
Đúng, như svick gợi ý, nó phụ thuộc vào việc bạn đang chạm vào giao diện người dùng của bạn từ một chuỗi khác (không đồng bộ) – gideon