C# Winform 图片文件管理器优化后续问题,为了优化图片的翻页速度,对文件管理器的移动文件动作进行了异步队列处理。过程中遇到了新的问题,当然了,这个问题调查后发现并不是由异步队列引起的。在之前的版本中频繁刷新当页文件也会出现参数无效 Parameter is not valid 的异常。先总结调查后的原因:PictureBox的Image释放后,同时释放了缓存中的Image。下次加载此图片时,由于缓存图片已经释放导致赋值给PictureBox.Image时出现异常 Parameter is not valid。
<code><span class="typ">ArgumentException</span><span class="pun">:</span> <span class="typ">Parameter</span> <span class="kwd">is</span><span class="pln"> not valid</span><span class="pun">.</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Drawing</span><span class="pun">.</span><span class="typ"><a href="https://www.codebye.com/tag/image" title="查看更多关于Image的文章" target="_blank">Image</a></span><span class="pun">.</span><span class="pln">get_FrameDimensionsList</span><span class="pun">()</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Drawing</span><span class="pun">.</span><span class="typ"><a href="https://www.codebye.com/tag/image" title="查看更多关于Image的文章" target="_blank">Image</a>Animator</span><span class="pun">.</span><span class="typ">CanAnimate</span><span class="pun">(</span><span class="typ"><a href="https://www.codebye.com/tag/image" title="查看更多关于Image的文章" target="_blank">Image</a></span><span class="pln"> image</span><span class="pun">)</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Drawing</span><span class="pun">.</span><span class="typ"><a href="https://www.codebye.com/tag/image" title="查看更多关于Image的文章" target="_blank">Image</a>Animator</span><span class="pun">.</span><span class="typ">ImageInfo</span><span class="pun">..</span><span class="pln">ctor</span><span class="pun">(</span><span class="typ">Image</span><span class="pln"> image</span><span class="pun">)</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Drawing</span><span class="pun">.</span><span class="typ">ImageAnimator</span><span class="pun">.</span><span class="typ">Animate</span><span class="pun">(</span><span class="typ">Image</span><span class="pln"> image</span><span class="pun">,</span> <span class="typ">EventHandler</span><span class="pln"> onFrameChangedHandler</span><span class="pun">)</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Windows</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">PictureBox</span><span class="pun">.</span><span class="typ">Animate</span><span class="pun">(</span><span class="typ">Boolean</span><span class="pln"> animate</span><span class="pun">)</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Windows</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">Control</span><span class="pun">.</span><span class="typ">AssignParent</span><span class="pun">(</span><span class="typ">Control</span><span class="pln"> value</span><span class="pun">)</span><span class="pln"> at </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Windows</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">Control</span><span class="pun">.</span><span class="typ">ControlCollection</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="typ">Control</span><span class="pln"> value</span><span class="pun">)</span><span class="pln"> at </span><span class="typ">codebye.com</span><span class="pun">.</span><span class="typ">StatusPaneUserControl</span><span class="pun">.</span><span class="typ">InitializeComponent</span><span class="pun">()</span><span class="pln"> at <span class="typ">codebye.com</span></span><span class="pun">.</span><span class="typ">MainForm</span><span class="pun">.</span><span class="typ">InitializeComponent</span><span class="pun">()</span><span class="pln"> at <span class="typ">codebye.com</span></span><span class="pun">.</span><span class="typ">MainForm</span><span class="pun">..</span><span class="pln">ctor</span><span class="pun">(</span><span class="typ">Action</span><span class="pln"> shutdown_request_callback</span><span class="pun">)</span></code>
首先介绍一下实现:
1、将当前文件夹内的图片缓存到了Dictionary<string,Image> ,其中key是图片路径,value是图片
2、显示时,取一定数量的图片文件显示在PictureBox控件集合中,PictureBox的父容器控件是FlowlayoutPanel
3、刷新时,移除当前FlowlayoutPanel中所有的PictureBox,重新加载显示新的PictureBox
最初给PictureBox.Image赋值直接使用的Dictionary缓存中的Image,二者引用了同一个对象,移除PictureBox控件时,调用了Image.Dispose导致了缓存被释放。
将 pictureBox.Image.Dispose();
改为: pictureBox.Image = null;