在更新绑定源期间冻结 wpf 应用程序
Posted
技术标签:
【中文标题】在更新绑定源期间冻结 wpf 应用程序【英文标题】:freeze wpf app during update binding source 【发布时间】:2013-11-30 05:40:21 【问题描述】:我基于 ListView 控件创建了缩略图。在ListView.ItemSource
我绑定ObservableColletion<Photos> Photosget;set
。
我也在另一个线程中以并行方式创建缩略图。
我简化了我的代码。
public class ThumbnailCreator
public static List<Photos> CreateThumbnailImage(List<Photos> photos)
var thumbnails = new List<Photos>();
Parallel.ForEach(photos, photo =>
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.DecodePixelHeight = 128;
bitmap.DecodePixelWidth = 128;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.CreateOptions = BitmapCreateOptions.DelayCreation;
bitmap.UriSource = new Uri(photo.FullPath);
bitmap.EndInit();
if (bitmap.CanFreeze)
bitmap.Freeze();
thumbnails.Add(new PhotosThumbnailImage = bitmap);
);
return thumbnails;
问题来了:
//I break binding before I start refreshing thumbnails
this.Thumbnails.ItemsSource = null;
//load files from folder
List<Photos> photos = _fileManager.LoadFromDir(folderBrowserDialog.SelectedPath);
//create thumbnail images in another threads, not on UI
List<Photos> thumbnails = ThumbnailCreator.CreateThumbnailImage(photos);
//create new source
Photos = new ObservableCollection<Photos>(thumbnails);
//reenable binding, this part of code cause that UI free
this.Thumbnails.ItemsSource = Photos;
当我重新启用绑定 UI 冻结时,我尝试使用调度程序但结果是相同的 UI 冻结。
this.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() =>
Photos = new ObservableCollection<Photos>(thumbnails);
this.Thumbnails.ItemsSource = Photos;
));
如何避免冻结 UI?
已编辑:
我根据 Dean K. 的建议编辑了我的代码。我不会在更新列表视图源之前打破绑定。
我通过 Dispatcher 更新了 ListView.ItemSource 的来源:
同步调用:
App.Current.Dispatcher.Invoke(new Action(() =>
thumbnails.Add(new Photos ThumbnailImage = bitmap );
), DispatcherPriority.ContextIdle);
结果 - 用户界面行为。
图像正在连续添加,但如果集合在 WPF 窗口中包含超过 500 个图像,则会冻结。例如不能移动窗口、滚动列表视图。
异步调用
App.Current.Dispatcher.InvokeAsync(new Action(() =>
thumbnails.Add(new Photos ThumbnailImage = bitmap );
), DispatcherPriority.ContextIdle);
结果 - 用户界面行为。
在启动应用程序冻结,但几秒钟后不断添加图像,也可以移动窗口,滚动列表视图。
所以我的问题是应用程序冻结的问题根源是什么?我怎样才能避免这种行为。 I upload sample application.
【问题讨论】:
【参考方案1】:在将项目添加到ObservableCollection
之前不要破坏绑定。
将Thumbnails.ItemsSource
绑定到Photos
OC,然后在另一个线程加载并将项目添加到Photos
OC。这样你的用户界面就不会冻结。
您可能希望使用在代码项目中可以找到的多线程 ObservableColleciton。搜索 ObservableCollectionMt...
【讨论】:
我根据您的建议编辑了我的示例,但应用程序仍然冻结。更多细节在我原来的问题中。以上是关于在更新绑定源期间冻结 wpf 应用程序的主要内容,如果未能解决你的问题,请参考以下文章