多线程的操作与数据绑定
关于多线程的问题,一直没有弄太懂, 今天在 CodeProject 上看到一个很好的讲解多线程例子, 为增强理解,用我自己理解的方式记录下来,以便遗忘后查看。
如下图所示, 点击启动进度条后, 进度条会开始变化。
代码如下:
1 private void btnStartProg_Click(object sender, RoutedEventArgs e) 2 { 3 startN = Convert.ToInt32(startNum.Text); 4 endN = Convert.ToInt32(endNum.Text); 5 6 progBar.Minimum = startN; 7 progBar.Maximum = endN; 8 9 for (int progValue = startN; progValue < endN; progValue++) 10 { 11 progBar.Value = progValue; 12 } 13 }
当 End 数值大于10e6 时, 会出线界面无响应状态,如下图所示:
之所以有这种情况是因为单线程条件下, 当数值过大时候, 线程阻塞在 for 循环位置, 来不及更新界面。
要解决这个问题很简单, 在 UI 线程外增加一个新的线程(wpf中采用dispatcher.invoke, 若不是在UI线程中, 可采用事件的形式),使得进度条的变化在另一线程中进行。
1 private void btnStartProg_Click(object sender, RoutedEventArgs e) 2 { 3 startN = Convert.ToInt32(startNum.Text); 4 endN = Convert.ToInt32(endNum.Text); 5 6 progBar.Minimum = startN; 7 progBar.Maximum = endN; 8 9 System.Threading.Thread changeValueThread = new System.Threading.Thread(ChangeProgessValue); 10 changeValueThread.Start(); 12 } 13 14 private void ChangeProgessValue() 15 { 16 for (int progValue = startN; progValue < endN; progValue++) 17 { 18 Dispatcher.Invoke(() => progBar.Value = progValue); 19 } 20 }
另一种处理多线程的通信方式可基于事件机制进行通信, 具体如下图所示(参考 https://www.jianshu.com/p/8faae685a468):
在 wpf 中, 当界面的某个值大量的变化的时候,采用绑定属性(全局变量)的方式,免去根据 Name 来查找控件位置, 速度会快很多。
具体代码如下:
1 // 类继承 INotifyPropertyChanged, 实现并重载事件处理方法 2 public event PropertyChangedEventHandler PropertyChanged; 3 protected virtual void OnpropertyChanged(string propertyName) 4 { 5 if(this.PropertyChanged != null) 6 { 7 this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)) 8 } 9 } 10 // 定义一个属性 11 private int currentValue; 12 public int CurrentValue 13 { 14 get {return currentValue} 15 set 16 { 17 currentValue = value; 18 OnpropertyChanged("CurrentValue"); 19 } 20 } 21 22 // 然后在 .xmal 需要改变的值得位置添加值绑定 Value = "{Binding CurrentValue}"