各位大佬,最近用户反馈程序的图像加载慢,而且影响了数据显示。具体情况是这样的:界面上一个重写的Listview用来显示用户信息,然后下边有一个自定义的控件原来加载当前选中行用户的图像,用selectedindexchanged事件绑定的,后来发现图像过多时加载速度就变慢,这是因为查询数据库导致的,和图像加载本身无关。但是切换选中行时,从点击切换到切换结束的几秒中,listview的切换的这两行被清空了,重绘的数据文字和选中背景色都消失了,下面的Image控件图像加载完毕之后才恢复正常,感觉好像重绘的过程被暂停了,影响用户体验。同样的控件,用户图像数据少,查询速度比较快的时候切换行重绘救很快,肉眼不可见,这和selectedindexchanged事件的机制有关吗?将selectedindexchanged事件里面的数据查询和加载图像单独创建线程处理,也没什么效果。
用户图像是存在本地的,不用下载缓存,我进行了尝试,发现耗费的时间主要是在查询当前选中用户的图像路径上,这块暂时不准备进行修改,数据多了,当然耗费时间。其实真正加载图像并不耗时。现在主要的问题是,触发selectedindexchanged事件,这个时候,Listview会进行重绘,大概流程是:清空之前选中行的选中背景色,将其绘制成未选中的,把将要选中的行背景色改为选中行背景色。当我查询数据多,耗时的时候,感觉这个流程卡住了一样,之前选中的行背景色和数据都清空了,后面将要选中的行数据清空了,颜色也没绘制。直到我查询完毕。给人的感觉就是: selectedindexchanged事件触发-->之前选中行背景色清空;数据查询及图像加载-->界面重绘暂停(若干秒,两行的背景色和数据都清空了,影响用户体验,就是这个问题);selectedindexchanged事件结束-->重绘,然后完成。
我不太清楚为什么selectedindexchanged事件会和Listview的重绘关联了,我试图将数据查询及图像加载这一块用线程单独执行,然并卵。
这可能是因为加载图像的过程是UI线程同步的,由于图像下载太慢,造成下载期间界面无法刷新。
碰到这种问题,耐心是很重要的。
1、用户图像有多大?
2、下载用了多少时间?
3、能否本地缓存?
4、SelectedIndexChanged 事件太频繁也会造成一个问题,参考一下React 编程模式中的一个解决方案可以有效减少无效查询。
5、看一下是否重写的ListView控件有改良的空间。
用户图像是存在本地的,不用下载缓存,我进行了尝试,发现耗费的时间主要是在查询当前选中用户的图像路径上,这块暂时不准备进行修改,数据多了,当然耗费时间。其实真正加载图像并不耗时。现在主要的问题是,触发selectedindexchanged事件,这个时候,Listview会进行重绘,大概流程是:清空之前选中行的选中背景色,将其绘制成未选中的,把将要选中的行背景色改为选中行背景色。当我查询数据多,耗时的时候,感觉这个流程卡住了一样,之前选中的行背景色和数据都清空了,后面将要选中的行数据清空了,颜色也没绘制。直到我查询完毕。给人的感觉就是: selectedindexchanged事件触发-->之前选中行背景色清空;数据查询及图像加载-->界面重绘暂停(若干秒,两行的背景色和数据都清空了,影响用户体验,就是这个问题);selectedindexchanged事件结束-->重绘,然后完成。
我不太清楚为什么selectedindexchanged事件会和Listview的重绘关联了,我试图将数据查询及图像加载这一块用线程单独执行,然并卵。
主要向吧图像查询及加载和selectedindexchanged事件分开。
其实最终问题是因为我把数据查询和图像加载放在一个线程里面执行,然而图像加载最终还是要操作UI线程来执行,所以用了BeginInvoke,后来查了才知道,BeginInvoke实际上还是在UI线程中执行,又饶了回来。最后把数据查询和图像加载分开,创建线程执行数据查询,然后用变量存起来,然后BeginInvoke再加载,就解决了。
@实习1号: 是的,这是很多人容易出现的问题,必须学会如何把一个长流程慢慢掰成很多个段,理解每一个段的成本。