SyncizationContext cung cấp cho chúng ta cách cập nhật giao diện người dùng từ một luồng khác (đồng bộ thông qua phương thức Gửi hoặc không đồng bộ qua phương thức Đăng).
Hãy xem ví dụ sau:
private void SynchronizationContext SyncContext = SynchronizationContext.Current;
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(Work1);
thread.Start(SyncContext);
}
private void Work1(object state)
{
SynchronizationContext syncContext = state as SynchronizationContext;
syncContext.Post(UpdateTextBox, syncContext);
}
private void UpdateTextBox(object state)
{
Thread.Sleep(1000);
string text = File.ReadAllText(@"c:\temp\log.txt");
myTextBox.Text = text;
}
SyncizationContext.C hiện tại sẽ trả về bối cảnh đồng bộ hóa của giao diện người dùng. Làm thế nào để tôi biết điều này? Khi bắt đầu mọi hình thức hoặc ứng dụng WPF, bối cảnh sẽ được đặt trên luồng UI. Nếu bạn tạo một ứng dụng WPF và chạy ví dụ của tôi, bạn sẽ thấy rằng khi bạn nhấp vào nút, nó sẽ ngủ trong khoảng 1 giây, sau đó nó sẽ hiển thị nội dung của tệp. Bạn có thể mong đợi nó sẽ không bởi vì người gọi phương thức UpdateTextBox (là Work1) là một phương thức được truyền cho một Chủ đề, do đó, nó sẽ ngủ chủ đề đó không phải là chủ đề UI chính, NOPE! Mặc dù phương thức Work1 được truyền đến một luồng, lưu ý rằng nó cũng chấp nhận một đối tượng là SyncContext. Nếu bạn nhìn vào nó, bạn sẽ thấy phương thức UpdateTextBox được thực thi thông qua phương thức syncContext.Post chứ không phải phương thức Work1. Hãy xem những điều sau đây:
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread.Sleep(1000);
string text = File.ReadAllText(@"c:\temp\log.txt");
myTextBox.Text = text;
}
Ví dụ cuối cùng và cái này thực hiện giống nhau. Cả hai đều không chặn UI trong khi nó hoạt động.
Để kết luận, hãy nghĩ về SyncizationContext như một luồng. Nó không phải là một luồng, nó xác định một luồng (Lưu ý rằng không phải tất cả các luồng đều có SyncContext). Bất cứ khi nào chúng tôi gọi phương thức Đăng hoặc Gửi trên đó để cập nhật giao diện người dùng, thì cũng giống như cập nhật giao diện người dùng thông thường từ luồng giao diện người dùng chính. Nếu, vì một số lý do, bạn cần cập nhật UI từ một luồng khác, hãy đảm bảo rằng luồng đó có SyncContext của luồng UI chính và chỉ gọi phương thức Gửi hoặc Đăng trên đó bằng phương thức mà bạn muốn thực thi và bạn là tất cả bộ.
Hy vọng điều này sẽ giúp bạn, bạn đời!