如题,当显示几张图片的时候速度还行,但是当显示100张图片(图片缩略图也不行)的时候反应超慢,而且PF使用率一直是1.7G左右,除非关闭程序才可以降下来。加载图片代码如下for (int i = 0; i < 100; i++){
    Image image = new Image();
    image.Width = 100;
    image.Height = 90;
    BitmapImage bi = new BitmapImage();
    bi.BeginInit();
    bi.CacheOption = BitmapCacheOption.None;
    bi.CreateOptions = BitmapCreateOptions.DelayCreation;
    bi.UriSource = new Uri(thnumbnailPath, UriKind.RelativeOrAbsolute);
    bi.EndInit();
    image.Source = bi;
    bi.Freeze();
    image.DataContext = picPath1;
    image.ToolTip = "名称:XXX";
    audioListBox.Items.Add(image);
}大神小神们都帮忙看看,不要让帖子沉了啊,谢了!

解决方案 »

  1.   

    你这是在主线程加载图片当然慢,UI没法反应,建议写个ObservableCollection<Uri>,绑定到listbox上,异步加载图片。
      

  2.   

    绑定,然后把虚拟化打开,会好一点
    试完看看是否可以接受。
    不能接受再谈别的方法,不管怎么说,瞬间加载一大堆图片是很不明智的。
    最简单的东西,windows的文件夹当打开一对文件缩略图的时候也很慢。
      

  3.   

    listbox 加载大量图片的时候还是使用多线程吧!你这样加载肯定会卡主的。
      

  4.   

    你这是一次性初始化100张图片,再在UI显示,当然慢的。我的意思是你的listbox去绑定数据源imagelist。
    imagelist class里写个函数去异步初始化加载图片。
    这样在UI中的效果是,一张张图片显示出来,不会阻碍ui的流畅性。
    如同微博,不可能读完所有的微博内容数据,再在ui显示的啊。
      

  5.   


    谢谢!新手初学WPF,不太会,能不能给代码啊
      

  6.   

    private void GetAllImage() { Image image = new Image();
    image.Width = 100;
            image.Height = 90;
    new Thread(new ThreadStart(() => {
    for (int i = 0; i < 100; i++){
    BitmapImage bitmap = new BitmapImage();
    bitmap.BeginInit();
    bi.UriSource = new Uri(thnumbnailPath, UriKind.RelativeOrAbsolute); // thnumbnailPath为图片缩略图路径
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.EndInit();
    bitmap.Freeze();
        Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,(Action)(() => {
    image.Source = bi;
            image.DataContext = picPath1; // picPath1为原图路径
            image.ToolTip = "名称:XXX" ;
            audioListBox.Items.Add(image);
    }));
    }
    })).Start();
    }以上代码是不是所谓的异步加载?但是audioListBox.Items.Add(image);这一句报错:调用的目标发生了异常!InnerException: System.InvalidOperationException
           Message="元素已具有逻辑父级。将其附加到新的父级之前必须将其与旧父级断开。"
      

  7.   

        class ImageUri : INotifyPropertyChanged
        {
           private Uri m_uri;        public event PropertyChangedEventHandler PropertyChanged;        private void NotifyPropertyChanged(String info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }        public Uri ResourceUri
            {
                get
                {
                    return this.m_uri;
                }
                set
                {
                    if (value != this.m_uri)
                    {
                        ResourceUri = value;
                        NotifyPropertyChanged("ResourceUri");
                    }
                }
            }
        }    class ImageList : ObservableCollection<ImageUri>
        {
            public void init()
            {
                Task.Factory.StartNew<ObservableCollection<ImageUri>>(() =>
                {
                    ObservableCollection<ImageUri> tempList = new ObservableCollection<ImageUri>();
                    for(int i = 0; i < 100; i++)
                    {
                        tempList.Add(new ImageUri() { ResourceUri = creatImageSourceUri("") });   //your image source 
                    }
                    return tempList;
                }).ContinueWith(op =>
                {
                    foreach (ImageUri temp in op.Result)
                    {
                        this.Add(temp);
                    }
                   
                }, TaskScheduler.FromCurrentSynchronizationContext());        }
            public Uri creatImageSourceUri(string imageName)
            {            BitmapImage myBitmapImage = new BitmapImage();
                myBitmapImage.BeginInit();            myBitmapImage.UriSource = new Uri(UserDir.imageDir + @"\" + imageName);
                // To save significant application memory, set the DecodePixelWidth or  
                // DecodePixelHeight of the BitmapImage value of the image source to the desired 
                // height or width of the rendered image. If you don't do this, the application will 
                // cache the image as though it were rendered as its normal size rather then just 
                // the size that is displayed.
                // Note: In order to preserve aspect ratio, set DecodePixelWidth
                // or DecodePixelHeight but not both.
                myBitmapImage.DecodePixelWidth = 200;
                myBitmapImage.EndInit();            return myBitmapImage.UriSource;        }
        }在xaml里写上
            <ListBox Name="listbox1" ItemsSource="{Binding}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding Path=ResourceUri}"></Image>
                    </DataTemplate>            </ListBox.ItemTemplate>
            </ListBox>在主界面初始化写ImageList imageList = new ImageList ();
    listbox1.DataContext = imageList;
    imageList.init();
      

  8.   

    XAML 一直有效率问题.不知道为什么,并且界面不能多CPU进行处理,会把一个核心点用完.
      

  9.   

    尽量让主进程少处理IO或者网络请求,效率是不会有多大问题的。目前的客户端编程技术都是运行在一个核上的,除非用特殊的语言,类似于cuda之类的GPU并行语言。不同的进程运行在不同的核是靠操作系统调度的。
      

  10.   

    十分感谢zhleiyang提供代码,我在调试时Task找到对应的程序集了但是TaskScheduler怎么都找不到;我用以下代码实现将图片一张张显示出来,但是PF使用率还是持高不下啊,大家有没有解决的方法呢
    private void GetAllImage() {new Thread(new ThreadStart(() => {
    for (int i = 0; i < 100; i++){
    BitmapImage bitmap = new BitmapImage();
    bitmap.BeginInit();
    bi.UriSource = new Uri(thnumbnailPath, UriKind.RelativeOrAbsolute); // thnumbnailPath为图片缩略图路径
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.EndInit();
    bitmap.Freeze();
    Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,(Action)(() => {
      Image image = new Image();
      image.Width = 100;
      image.Height = 90;
      image.Source = bi;
      image.DataContext = picPath1; // picPath1为原图路径
      image.ToolTip = "名称:XXX" ;
      audioListBox.Items.Add(image);
    }));
    }
    })).Start();
    }
      

  11.   

    不会查下msdn么,mscorlib.dll,鼠标移到TaskScheduler上,按ctrl+.  ,就会出命名空间了。你的程序
    BitmapImage bitmap = new BitmapImage();
    bitmap.BeginInit();
    bi.UriSource = new Uri(thnumbnailPath, UriKind.RelativeOrAbsolute); // thnumbnailPath为图片缩略图路径
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.EndInit();
    bitmap.Freeze();
    这一段干嘛用? 我看不出你这段代码起什么作用。 image.DataContext = picPath1; 这条语句又是为何? 重新载入一次?而且使用 wpf,不用数据绑定,很奇怪。