在开发WPF应用程序时,UI线程不做高负载的工作,需要交给其他工作者线程去干。当工作者线程干完活得到一个结果后需要发送给UI线程进行展示,那最好的方法就是使用委托机制了。如果你不信邪,偏要在工作者线程里面调用控件去直接更新,这除了说明你对UI绘制的流程不了解之外,还说明你很固执。不仅仅是WPF这样,安卓也是这么一个机制。
下面代码展示了如何适用委托机制来实现UI的更新。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 using System.Threading.Tasks; 7 using System.Windows; 8 using System.Windows.Controls; 9 using System.Windows.Data; 10 using System.Windows.Documents; 11 using System.Windows.Input; 12 using System.Windows.Interop; 13 using System.Windows.Media; 14 using System.Windows.Media.Imaging; 15 using System.Windows.Navigation; 16 using System.Windows.Shapes; 17 18 namespace DlgtTest 19 { 20 /// <summary> 21 /// Interaction logic for MainWindow.xaml 22 /// </summary> 23 public partial class MainWindow : Window 24 { 25 // 声明委托类型,相当于C语言里面typedef一个函数指针类型 26 private delegate void UIUpdaterCallback(string what); 27 // 定义一个委托对象,它还没有被实例化 28 private UIUpdaterCallback mUpdateCallback; 29 30 private uint mButtonClickedCount = 0; 31 32 public MainWindow() 33 { 34 InitializeComponent(); 35 CtrlTextBox.Clear(); 36 37 // 将推脱对象实例化,实例化的构造函数传入的就是实际要被执行的函数 38 mUpdateCallback = new UIUpdaterCallback(UIUpdaterEntry); 39 40 // 创建并启动一个线程,它里面发消息给UI线程做更新 41 Thread t = new Thread(new ThreadStart(ThreadEntry)); 42 // 一定要设置 IsBackground 为 true,除非这个线程能够自动退出 43 t.IsBackground = true; 44 t.Start(); 45 } 46 47 private void UIUpdaterEntry(string what) 48 { 49 if (null == what) 50 { 51 CtrlTextBox.AppendText("空字符串消息\n"); 52 return; 53 } 54 CtrlTextBox.AppendText(what); 55 CtrlTextBox.ScrollToEnd(); 56 } 57 58 private void CtrlButton_Click(object sender, RoutedEventArgs e) 59 { 60 mButtonClickedCount++; 61 string msg = "我作为一个按键已经被第 " + mButtonClickedCount + " 按下了。\n"; 62 this.Dispatcher.Invoke(mUpdateCallback, new object[] { msg }); 63 } 64 65 private void ThreadEntry() 66 { 67 string msg; 68 uint count = 0; 69 70 while(true) 71 { 72 Thread.Sleep(1000); 73 count++; 74 msg = "我作为一个线程已经休眠 " + count + " 秒了。\n"; 75 this.Dispatcher.Invoke(mUpdateCallback, new object[] { msg }); 76 } 77 } 78 } 79 }主窗口类
1 <Window x:Class="DlgtTest.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:DlgtTest" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Grid> 10 <Grid.RowDefinitions> 11 <RowDefinition Height="4*"></RowDefinition> 12 <RowDefinition Height="*"></RowDefinition> 13 </Grid.RowDefinitions> 14 <TextBox x:Name="CtrlTextBox" Grid.Row="0" Margin="5,5,5,5" VerticalScrollBarVisibility="Visible"></TextBox> 15 <Button x:Name="CtrlButton" Grid.Row="1" Margin="5,5,5,5" Click="CtrlButton_Click">Test</Button> 16 </Grid> 17 </Window>窗口布局XML
程序运行截图
需要注意的是创建的新线程如果要随着窗口关闭时自动结束,那就必须要设置“IsBackground”为真,否则你把窗口关闭了,后台的线程还是在执行的,你在系统的任务管理器里面可以看到这个窗口对应的进程还在跑着。
标签:委托,Windows,System,private,线程,UI,using,WPF From: https://www.cnblogs.com/ssdq/p/17014555.html