多线程的操作与数据绑定

关于多线程的问题,一直没有弄太懂, 今天在 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}"

 

posted on 2018-01-05 11:04  张居斜  阅读(1126)  评论(0编辑  收藏  举报

导航