我基于ListView控件创建了缩略图。在ListView.ItemSource
{绑定ObservableColletion<Photos> Photos{get;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 Photos{ThumbnailImage = 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;
}));
如何避免冻结用户界面?
编辑:
我根据Dean K.的建议编辑了我的代码。在更新listview的源代码之前我不会破坏绑定。
我通过Dispatcher更新了ListView.ItemSource的源代码:
同步发票:
App.Current.Dispatcher.Invoke(new Action(() =>
{
thumbnails.Add(new Photos { ThumbnailImage = bitmap });
}), DispatcherPriority.ContextIdle);
结果 - 用户界面行为。
正在连续添加图像,但如果集合中包含超过500个图像,则WPF窗口会冻结。例如,无法移动窗口,滚动列表视图。
异步调用
App.Current.Dispatcher.InvokeAsync(new Action(() =>
{
thumbnails.Add(new Photos { ThumbnailImage = bitmap });
}), DispatcherPriority.ContextIdle);
结果 - 用户界面行为。
在开始应用程序冻结但几秒钟后连续添加图像,也可以移动窗口,滚动列表视图。
所以我的问题是应用冻结的问题根源是什么?我怎样才能避免这种行为。 I upload sample application
答案 0 :(得分:1)
在将项目添加到ObservableCollection
之前,请勿破坏绑定。
将Thumbnails.ItemsSource
绑定到Photos
OC,然后绑定到另一个线程,并将项目添加到Photos
OC。这样你的UI就不会冻结。
您可能希望使用可在代码项目中找到的多线程ObservableColleciton。搜索ObservableCollectionMt ...