【问题标题】:freeze wpf app during update binding source在更新绑定源期间冻结 wpf 应用程序
【发布时间】:2013-11-30 05:40:21
【问题描述】:

我基于 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;
                }));

如何避免冻结 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.

【问题讨论】:

    标签: wpf listview binding freeze


    【解决方案1】:

    在将项目添加到ObservableCollection 之前不要破坏绑定。

    Thumbnails.ItemsSource 绑定到Photos OC,然后在另一个线程加载并将项目添加到Photos OC。这样你的用户界面就不会冻结。

    您可能希望使用在代码项目中可以找到的多线程 ObservableColleciton。搜索 ObservableCollectionMt...

    【讨论】:

    • 我根据您的建议编辑了我的示例,但应用程序仍然冻结。更多细节在我原来的问题中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2014-07-18
    • 2012-12-05
    • 2011-11-07
    • 2020-10-02
    • 1970-01-01
    相关资源
    最近更新 更多