WPF在ListBox中显示图片响应慢,怎么办?

maoj0109 2012-09-11 01:24:11
如题,当显示几张图片的时候速度还行,但是当显示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);
}

大神小神们都帮忙看看,不要让帖子沉了啊,谢了!
...全文
966 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdzzlove 2013-01-15
  • 打赏
  • 举报
回复
引用 15 楼 maoj0109 的回复:
问题解决了!谢谢!
请问问题怎么解决的啊?
maoj0109 2012-09-13
  • 打赏
  • 举报
回复
问题解决了!谢谢!
zhleiyang 2012-09-12
  • 打赏
  • 举报
回复
不会查下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,不用数据绑定,很奇怪。
maoj0109 2012-09-12
  • 打赏
  • 举报
回复
十分感谢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();
}
zhleiyang 2012-09-11
  • 打赏
  • 举报
回复
尽量让主进程少处理IO或者网络请求,效率是不会有多大问题的。目前的客户端编程技术都是运行在一个核上的,除非用特殊的语言,类似于cuda之类的GPU并行语言。不同的进程运行在不同的核是靠操作系统调度的。
生财 2012-09-11
  • 打赏
  • 举报
回复
XAML 一直有效率问题.不知道为什么,并且界面不能多CPU进行处理,会把一个核心点用完.
zhleiyang 2012-09-11
  • 打赏
  • 举报
回复
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();

zhleiyang 2012-09-11
  • 打赏
  • 举报
回复
我写个代码给你把
zhleiyang 2012-09-11
  • 打赏
  • 举报
回复
肯定异常了,因为你在次线程里,使用主线程的资源。跨线程使用资源。
maoj0109 2012-09-11
  • 打赏
  • 举报
回复
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="元素已具有逻辑父级。将其附加到新的父级之前必须将其与旧父级断开。"
maoj0109 2012-09-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

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

能不能给具体代码啊,新手而且任务很紧,谢了
maoj0109 2012-09-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

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

谢谢!新手初学WPF,不太会,能不能给代码啊
zhleiyang 2012-09-11
  • 打赏
  • 举报
回复
你这是一次性初始化100张图片,再在UI显示,当然慢的。我的意思是你的listbox去绑定数据源imagelist。
imagelist class里写个函数去异步初始化加载图片。
这样在UI中的效果是,一张张图片显示出来,不会阻碍ui的流畅性。
如同微博,不可能读完所有的微博内容数据,再在ui显示的啊。
xfy_dabing 2012-09-11
  • 打赏
  • 举报
回复
listbox 加载大量图片的时候还是使用多线程吧!你这样加载肯定会卡主的。
cheng2005 2012-09-11
  • 打赏
  • 举报
回复
绑定,然后把虚拟化打开,会好一点
试完看看是否可以接受。
不能接受再谈别的方法,不管怎么说,瞬间加载一大堆图片是很不明智的。
最简单的东西,windows的文件夹当打开一对文件缩略图的时候也很慢。
zhleiyang 2012-09-11
  • 打赏
  • 举报
回复
你这是在主线程加载图片当然慢,UI没法反应,建议写个ObservableCollection<Uri>,绑定到listbox上,异步加载图片。

110,572

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧