MY ViewModel类包含两个字符串属性(Filename和ThumbnailPath),其DataTemplate包含绑定到这些属性的Label和Image。
void bw_DoWork (object sender, DoWorkEventArgs e) {
List<string> files = e.Argument as List<string>;
FileInfo fi; int percent;
for (int i = 0; i < files.Count; i++) {
FileViewModel newItem = new FileViewModel(files[i]);
fi = new FileInfo(files[i]);
percent = i / files.Count * 100;
bwImportBrowserItems.ReportProgress(percent, newItem);
}
}
void bw_ProgressChanged (object sender, ProgressChangedEventArgs e) {
this.observableCollection.Add(e.UserState as FileViewModel);
}
典型数量的项目(30-50)的典型行为:UI冻结约2-3秒;大约一半的项目显示; UI会在较短的时间内再次冻结,其余部分会被添加。
现在我明白从循环中调用UI更新并不是最好的主意 - 我认为调用很频繁,用户界面没有时间回应它们,这就是为什么我们看到UI正在更新&#34;在组&#34;中,同时让它无响应。
我尝试添加Thread.Sleep(500)
作为循环的最后一行。这有助于我说明一切正常,因为随着这种减速,项目被添加很好地一个接一个地没有任何无反应。
所以我尝试了不同的睡眠值,为Thread.Sleep(25)
确定了。这不是理想的,但是完全可以接受,并且非常接近它的样子。
我想在这种情况下询问Thread.Sleep是否是一种常见的解决方法,以及在这种情况下人们采用的一般解决方案是什么:更新UI从背景循环收集而没有任何反应迟钝。 我也提出了一些想法,我很感激你的意见。
我能想到的想法:
答案 0 :(得分:1)
如果Thread.Sleep是这些情况下的常见解决方法
将它视为最后的手段。您正在增加总处理时间(而不是CPU负载)。
1)不要频繁报告ReportProgress - 将其限制为10次,或者每10个新项目。
这是基本的想法。收集新项目并通过ReportProgess发送List。调整列表的大小。
2)不要在循环中进行。
可能,但是每个Bgw的1件物品看起来要慢得多。它甚至可能表现出相同的症状。
3)通过ConcurrentQueue去耦。您可以让DoWork填充队列和Dispatcher.Timer可以清空它。还尝试使用该计时器处理批次。您可以调整计时器的优先级和批量大小。