在編寫代碼時,我們經常會碰到一些子線程中處理完的信息,需要通知另一個線程(我這邊處理完了,該你了)。
但是當我們通知WPF的UI線程時需要用到Dispatcher。
首先我們需要想好在UI控件上需要顯示什么內容。然后寫一個顯示UI內容的方法。
以下是代碼
private void UIThreaddosomething(string s) //UI線程要做的事情 { //do something //這里也可以做一些其他的事情 Label2.Content = s; ellipse1.Fill=new SolidColorBrush(Colors.Red); ellipse2.Fill=new SolidColorBrush(Colors.Red); }
然后我們聲明一個委托,由於UIThreaddosomething有一個字符串參數,所以聲明的委托要與其保持一致
public delegate void RefleshUI(string s);
然后在創建一個方法,這個方法將通過委托將子線程與UI線程聯系起來。
private void delegatedosomething(string s) { ellipse1.Dispatcher.Invoke(new RefleshUI(UIThreaddosomething), s); // ellipse2.Dispatcher.Invoke(new RefleshUI(UIThreaddosomething), s); }
這里我之前以為只要UI控件里有多少控件,就需要在此方法里用多少個Dispatcher,最后發現是我太年輕,只需要一個控件用上Dispatcher就好啦。
這里我們就可以跨線程訪問WPF的UI控件了
完整代碼如下,(這里我們也還可以使用一個中間方法來調用了UI方法,這樣當程序有多個UI方法時,我們可以在這個中間方法中做一些處理,然后決定引用那些UI方法)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Threading; namespace 子線程通知主線程做一些事情 { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public delegate void RefleshUI(string s); private void Button_Click(object sender, RoutedEventArgs e) { Thread th; th = new Thread(fun); th.IsBackground = true; th.Start(); } private void fun(object obj) { //////做一些子線程該做的事情 ///// ///// /**子線程完成后通知UI線程*/ delegatedosomething("你好,我是jjp_god,我做完了"); } private void delegatedosomething(string s) { ellipse1.Dispatcher.Invoke(new RefleshUI(dofun), s); // ellipse2.Dispatcher.Invoke(new RefleshUI(UIThreaddosomething), s); } private void UIThreaddosomething(string s) //UI線程要做的事情 { //do something //這里也可以做一些其他的事情 tb_show.Text = s; Label2.Content = s; ellipse1.Fill=new SolidColorBrush(Colors.Red); ellipse2.Fill=new SolidColorBrush(Colors.Red); } private void dofun(string s) { UIThreaddosomething(s); } }
}