当前位置:   article > 正文

【WPF】异步任务更新UI、绑定命令、绑定字符串属性_wpf异步更新ui

wpf异步更新ui

WPF异步任务

主界面

属性改变触发UI更新:

  1. //打印的内容:文本框显示的内容
  2. public string PrintNumbers
  3. {
  4. get { return printNumbers; }
  5. set
  6. {
  7. printNumbers = value;
  8. RaisePropertyChanged();
  9. }
  10. }
  1. <TextBox Name="Execution" HorizontalAlignment="Right"
  2. Height="649" Margin="0,10,10,0" TextWrapping="Wrap"
  3. ScrollViewer.HorizontalScrollBarVisibility="Visible"
  4. ScrollViewer.VerticalScrollBarVisibility="Auto"
  5. Text="{Binding PrintNumbers,Mode=TwoWay,
  6. UpdateSourceTrigger=PropertyChanged}"
  7. VerticalAlignment="Top" Width="692" Grid.Column="1" />

命令绑定:

在视图模型中定义命令:

  1. //绑定的命令
  2. public ICommand StartButtonCommand { get; set; }
  3. public ICommand AddTaskCommand { get; set; }
  4. public ICommand ClearAllData { get; set; }

在主界面xaml中绑定命令:

  1. <Button Content="Start Task" Height="36"
  2. Margin="10,30,797,0"
  3. VerticalAlignment="Top"
  4. Width="119" Command="{Binding StartButtonCommand}" Grid.Column="1"/>

 创建命令实例:

  1. StartButtonCommand = new DelegateCommand(TaskExecutionOrder);
  2. AddTaskCommand = new DelegateCommand(SelectedTaskExecution);
  3. ClearAllData = new DelegateCommand(ClearData);

绑定RadioButton属性:

  1. //radiobutton绑定的属性
  2. public bool IsOddChecked //选择奇数属性
  3. {
  4. get { return isOddChecked; }
  5. set { SetProperty(ref isOddChecked, value); RaisePropertyChanged(); }
  6. }
  7. //radiobutton绑定的属性
  8. public bool IsEvenChecked//选择偶数属性
  9. {
  10. get { return isEvenChecked; }
  11. set { SetProperty(ref isEvenChecked, value); RaisePropertyChanged(); }
  12. }
  1. <RadioButton x:Name="chckOddNum" Content="OddNumbers"
  2. HorizontalAlignment="Left" Margin="10,413,0,0"
  3. VerticalAlignment="Top"
  4. IsChecked="{Binding IsOddChecked,Mode=TwoWay,
  5. UpdateSourceTrigger=PropertyChanged}" Height="44" Width="119" RenderTransformOrigin="1,0.546" Grid.Column="1"/>

执行异步任务:

  1. private static Queue<Action> queue = new Queue<Action>();//操作队列
  2. private static readonly object queuelock = new object();//队列锁
Task.Run(() => ExecuteTasks());//执行异步任务,从队列中取出任务动作
  1. //开始按钮执行异步任务
  2. private async void ExecuteTasks()
  3. {
  4. while (true)
  5. {
  6. Action task = null;
  7. lock (queuelock)
  8. {
  9. if (queue.Count > 0)
  10. {
  11. task = queue.Dequeue();//取出一个任务操作
  12. }
  13. }
  14. if (task != null)
  15. {
  16. await Task.Run(() =>
  17. {
  18. task.Invoke();
  19. Thread.Sleep(100);
  20. });
  21. }
  22. }
  23. }
  1. //开始按钮委托命令 :执行 奇数、偶数任务
  2. public void TaskExecutionOrder()
  3. {
  4. queue.Enqueue(OddNumbers);
  5. queue.Enqueue(EvenNumbers);
  6. taskCount = queue.Count;//任务数
  7. }
  1. //奇数任务操作
  2. private void OddNumbers()
  3. {
  4. Dispatcher.CurrentDispatcher.Invoke(() =>
  5. {
  6. this.PrintNumbers += Environment.NewLine;
  7. this.PrintNumbers += Environment.NewLine;
  8. this.PrintNumbers += "OddNumbers between 1 to 100" + Environment.NewLine + "Task:" + " " + taskNumber.ToString();
  9. this.PrintNumbers += Environment.NewLine;
  10. this.ExecutionOrder += "Task:" + taskNumber.ToString() + "-Started" + "\n";
  11. });
  12. for (int i = 0; i <= 100; i++)
  13. {
  14. Dispatcher.CurrentDispatcher.Invoke(() =>
  15. {
  16. if (i % 2 != 0)//奇数
  17. {
  18. this.PrintNumbers += i.ToString() + " "; //属性改变,触发UI更新
  19. Thread.Sleep(10);
  20. }
  21. });
  22. }
  23. this.ExecutionOrder += "Task:" + taskNumber.ToString() + "-Stopped" + "\n";
  24. taskNumber++;//下一任务号
  25. Thread.Sleep(1000);
  26. }

完整代码:

XAML主界面:

  1. <Grid>
  2. <Grid.ColumnDefinitions>
  3. <ColumnDefinition Width="53*"/>
  4. <ColumnDefinition Width="739*"/>
  5. </Grid.ColumnDefinitions>
  6. <TextBox Name="Execution" HorizontalAlignment="Right"
  7. Height="649" Margin="0,10,10,0" TextWrapping="Wrap"
  8. ScrollViewer.HorizontalScrollBarVisibility="Visible"
  9. ScrollViewer.VerticalScrollBarVisibility="Auto"
  10. Text="{Binding PrintNumbers,Mode=TwoWay,
  11. UpdateSourceTrigger=PropertyChanged}"
  12. VerticalAlignment="Top" Width="692" Grid.Column="1" />
  13. <Button Content="Start Task" Height="36"
  14. Margin="10,30,797,0"
  15. VerticalAlignment="Top"
  16. Width="119" Command="{Binding StartButtonCommand}" Grid.Column="1"/>
  17. <RadioButton x:Name="chckOddNum" Content="OddNumbers"
  18. HorizontalAlignment="Left" Margin="10,413,0,0"
  19. VerticalAlignment="Top"
  20. IsChecked="{Binding IsOddChecked,Mode=TwoWay,
  21. UpdateSourceTrigger=PropertyChanged}" Height="44" Width="119" RenderTransformOrigin="1,0.546" Grid.Column="1"/>
  22. <RadioButton x:Name="chckEvenNum" Content="EvenNumbers"
  23. HorizontalAlignment="Left" Margin="10,462,0,0"
  24. VerticalAlignment="Top" IsChecked="{Binding IsEvenChecked,
  25. Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="42" Width="119" Grid.Column="1"/>
  26. <Button Content="Add Task" Height="31" HorizontalAlignment="Left"
  27. Margin="10,543,0,0" VerticalAlignment="Top" Width="119"
  28. Command="{Binding AddTaskCommand}" Grid.Column="1"/>
  29. <TextBox HorizontalAlignment="Left" Height="296"
  30. VerticalScrollBarVisibility="Auto"
  31. HorizontalScrollBarVisibility="Auto" Margin="31,88,0,0"
  32. VerticalAlignment="Top" Width="216"
  33. Text="{Binding ExecutionOrder,UpdateSourceTrigger=PropertyChanged}" Grid.ColumnSpan="2"/>
  34. <Button Content="ClearAll" HorizontalAlignment="Left" Margin="10,604,0,0"
  35. VerticalAlignment="Top" Command="{Binding ClearAllData,
  36. UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Width="119"
  37. Height="30" Grid.Column="1"/>
  38. </Grid>

主界面交互逻辑:

  1. namespace MultiThreadingWPF
  2. {
  3. using Prism.Commands;
  4. using Prism.Mvvm;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. using System.Windows.Input;
  10. using System.Windows.Threading;
  11. using MultiThreadingWPF.Model;
  12. public class MainWindowViewModel : BindableBase
  13. {
  14. private static Queue<Action> queue = new Queue<Action>();//操作队列
  15. private static readonly object queuelock = new object();//队列锁
  16. private string printNumbers;//打印的数字
  17. private string taskName;//任务名
  18. private static int taskNumber = 1;//任务号
  19. private TaskModel __taskModel;//任务模型 未使用
  20. private string executionOrder;// 执行订单
  21. private bool isOddChecked;//奇数选择字段
  22. private bool isEvenChecked;//偶数选择字段
  23. //绑定的命令
  24. public ICommand StartButtonCommand { get; set; }
  25. public ICommand AddTaskCommand { get; set; }
  26. public ICommand ClearAllData { get; set; }
  27. //任务数
  28. private int taskCount;
  29. //未使用TaskModel
  30. public TaskModel TasksModel
  31. {
  32. get { return __taskModel; }
  33. set { SetProperty(ref __taskModel, value); RaisePropertyChanged(); }
  34. }
  35. public string ExecutionOrder//
  36. {
  37. get { return executionOrder; }
  38. set { SetProperty(ref executionOrder, value); RaisePropertyChanged(); }
  39. }
  40. //radiobutton绑定的属性
  41. public bool IsOddChecked //选择奇数属性
  42. {
  43. get { return isOddChecked; }
  44. set { SetProperty(ref isOddChecked, value); RaisePropertyChanged(); }
  45. }
  46. //radiobutton绑定的属性
  47. public bool IsEvenChecked//选择偶数属性
  48. {
  49. get { return isEvenChecked; }
  50. set { SetProperty(ref isEvenChecked, value); RaisePropertyChanged(); }
  51. }
  52. //任务名
  53. public string TaskName
  54. {
  55. get { return taskName; }
  56. set
  57. {
  58. taskName = value;
  59. RaisePropertyChanged();
  60. }
  61. }
  62. //打印的内容:文本框显示的内容
  63. public string PrintNumbers
  64. {
  65. get { return printNumbers; }
  66. set
  67. {
  68. printNumbers = value;
  69. RaisePropertyChanged();
  70. }
  71. }
  72. //任务数
  73. public int TaskCount
  74. {
  75. get { return taskCount; }
  76. set { taskCount = value; RaisePropertyChanged(); }
  77. }
  78. //主窗体视图模型
  79. public MainWindowViewModel()
  80. {
  81. TasksModel = new TaskModel();
  82. StartButtonCommand = new DelegateCommand(TaskExecutionOrder);
  83. AddTaskCommand = new DelegateCommand(SelectedTaskExecution);
  84. ClearAllData = new DelegateCommand(ClearData);
  85. Task.Run(() => ExecuteTasks());
  86. }
  87. //添加(选择的radiobuttion)任务按钮 委托命令
  88. private void SelectedTaskExecution()
  89. {
  90. if(isEvenChecked)
  91. {
  92. Task.Run(()=>EvenNumbers());
  93. }
  94. else if(isOddChecked)
  95. {
  96. Task.Run(()=>OddNumbers());
  97. }
  98. else
  99. {
  100. this.PrintNumbers += "Please select any one Task to be executed"+"\n";
  101. }
  102. }
  103. //开始按钮委托命令 :执行 奇数、偶数任务
  104. public void TaskExecutionOrder()
  105. {
  106. queue.Enqueue(OddNumbers);
  107. queue.Enqueue(EvenNumbers);
  108. taskCount = queue.Count;
  109. }
  110. //开始按钮执行异步任务
  111. private async void ExecuteTasks()
  112. {
  113. while (true)
  114. {
  115. Action task = null;
  116. lock (queuelock)
  117. {
  118. if (queue.Count > 0)
  119. {
  120. task = queue.Dequeue();//取出一个任务操作
  121. }
  122. }
  123. if (task != null)
  124. {
  125. await Task.Run(() =>
  126. {
  127. task.Invoke();
  128. Thread.Sleep(100);
  129. });
  130. }
  131. }
  132. }
  133. //偶数任务操作
  134. private void EvenNumbers()
  135. { //线程池线程 调用UI控件绑定属性
  136. Dispatcher.CurrentDispatcher.Invoke(() =>
  137. {
  138. this.PrintNumbers += Environment.NewLine;
  139. this.PrintNumbers += Environment.NewLine;
  140. this.PrintNumbers += "EvenNumbers between 1 to 100" + Environment.NewLine + "Task:" + " " + taskNumber.ToString();
  141. this.PrintNumbers += Environment.NewLine;
  142. this.ExecutionOrder += "Task:" + taskNumber.ToString() + "-Started " + "\n";
  143. });
  144. for (int i = 0; i <= 100; i++)//偶数
  145. {
  146. Dispatcher.CurrentDispatcher.Invoke(() =>
  147. {
  148. if (i % 2 == 0)
  149. {
  150. this.PrintNumbers += i.ToString() + " ";
  151. Thread.Sleep(10);
  152. }
  153. });
  154. }
  155. this.ExecutionOrder += "Task:" + taskNumber.ToString() + "-Stopped" + "\n";
  156. taskNumber++;
  157. Thread.Sleep(1000);
  158. }
  159. //奇数任务操作
  160. private void OddNumbers()
  161. {
  162. Dispatcher.CurrentDispatcher.Invoke(() =>
  163. {
  164. this.PrintNumbers += Environment.NewLine;
  165. this.PrintNumbers += Environment.NewLine;
  166. this.PrintNumbers += "OddNumbers between 1 to 100" + Environment.NewLine + "Task:" + " " + taskNumber.ToString();
  167. this.PrintNumbers += Environment.NewLine;
  168. this.ExecutionOrder += "Task:" + taskNumber.ToString() + "-Started" + "\n";
  169. });
  170. for (int i = 0; i <= 100; i++)
  171. {
  172. Dispatcher.CurrentDispatcher.Invoke(() =>
  173. {
  174. if (i % 2 != 0)//奇数
  175. {
  176. this.PrintNumbers += i.ToString() + " ";
  177. Thread.Sleep(10);
  178. }
  179. });
  180. }
  181. this.ExecutionOrder += "Task:" + taskNumber.ToString() + "-Stopped" + "\n";
  182. taskNumber++;//下一任务号
  183. Thread.Sleep(1000);
  184. }
  185. //清空按钮 委托命令
  186. private void ClearData()
  187. {
  188. PrintNumbers = string.Empty;//文本框显示的内容
  189. }
  190. }
  191. }

任务模型 TaskModel.cs----未使用

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace MultiThreadingWPF.Model
  8. {
  9. public class TaskModel : INotifyPropertyChanged
  10. {
  11. private string TaskName { get; set; } //任务名
  12. private string PrintNumbers { get; set; } //打印的字符串
  13. public event PropertyChangedEventHandler PropertyChanged; //属性改变事件
  14. }
  15. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/884978
推荐阅读
相关标签
  

闽ICP备14008679号