| 一、 本文将解决什么问题?   本文将解决:在主线程绑定了数据源的前提下,工作线程改变数据源,数据源无法及时更新的问题。   二、问题是如何出现的?   UI控件属于UI线程。所有的绑定关系,是没办法穿透线程的。所以,在子线程中改变数据源的步骤,必须要‘回到UI线程’来进行。 当然,这与要避免在UI线程里进行耗时操作 的理念并不冲突。我们只在改变数据时回UI线程,切记。   三、问题代码 1. MainWindow.xaml:我在主窗体里存在以下这个控件  
  1 <telerik:RadGridView x:Name="rgvSendHist" Margin="10,8,10,41" Style="{StaticResource RadGridViewClean}" EnableColumnVirtualization="True" EnableRowVirtualization="True" IsReadOnly="True" Grid.Row="1" SelectionChanged="rgvSendHist_SelectionChanged">
 2                         <telerik:RadGridView.Columns>
 3                             <telerik:GridViewDataColumn DataMemberBinding="{Binding DataSend}" Header="数据包发送内容" Width="3*"/>
 4                             <telerik:GridViewDataColumn DataMemberBinding="{Binding RecLength,Mode=OneWay}" Header="返回包长度" Width="3*"/>
 5                             <telerik:GridViewDataColumn DataMemberBinding="{Binding SuccStatus,Mode=OneWay}"  Header="是否成功" Width="3*"/>
 6                         </telerik:RadGridView.Columns>
 7 </telerik:RadGridView> 2. MainWindow.xaml.cs: 我在这里进行了绑定。  
 1 ObservableCollection<TaskOfMany> aMultiTaskList = new ObservableCollection<TaskOfMany>();
2 
3 this.rgvTaskList.ItemsSource = aMultiTaskList; 3.MainWindow.xaml.cs: 我在这里通过线程对aMultiTaskList进行了改变。  
 1 foreach(TaskOfMany aTaskOfMany in aMultiTaskList)
2 {
3     new Task(() =>
4     {
5         aTaskOfMany.StartScan();
6     }).Start();
7 }     4.aTaskOfMany.StartScan内部:  
 1   this.TaskRunningStatus = TaskRunningStatusEnum.检测中;   此时,这个变化根本无法同步到控件上。   四、解决方案 在aTaskOfMany.StartScan内部改变值时,使用以下语句,回到UI线程:  
 1 Application.Current.Dispatcher.Invoke((Action)(() =>
2 {
3     TaskRunningStatus = TaskRunningStatusEnum.检测中;
4 })); 根据需要,你也可以使用BeginInvoke。至此,问题解决。 ------------------------------------------------------------------------------------------------------------------------ 分割线 ------------------------------------------------------------------------------------------------------------------------   对于大多数人来说,使用了以上的解决方案,你的问题就已经解决了。但是,对我来说,以上的方案并没有生效,让我一度怀疑连‘回到UI线程’这个解决方案也解决不了我的问题。 经过定位,我发现问题出在了我对线程最大数量的控制上:  
 1 ThreadPool.SetMaxThreads(10, 10); 设置了这句之后,貌似会影响invoke的创建(因为不能发起新线程了),所以就算用dispatcher回UI线程,也不能马上生效。。。   感谢群里的尚哥、三台等大神。真心感谢。   2017-5-10 10:27   |