【发布时间】:2012-02-26 17:21:38
【问题描述】:
我开发了一个应用程序,该应用程序使用 c# .net framework 4 中的 ImageList 在列表视图中加载了许多图像。图像也被压缩。当加载和压缩许多图像时,需要很长时间。所以我在后台调用该方法。在后台工作人员中,我必须将图像添加到 ImageList 并将 ImageList 添加到 ListView。所以我使用了 safeinvoke() 方法 listView1.SafeInvoke(d=>d.Items.Add(item))。 一切正常。图像在列表视图中一张一张显示。 但是应用程序的发布在某些电脑上不能正常工作,而在其他电脑上却能正常工作。不能正常工作的意思是,如果使用 OpenFileDialog 加载浏览了 100 张图片,则加载一些图片并添加到 listview,然后自动停止加载,而不将所有图片添加到 listview 并且没有异常显示。
我已经花了很多时间来解决这个问题,但无法弄清楚问题所在。 .问题出在哪里?有人可以帮帮我吗?
private void bgwLoading_DoWork(object sender, DoWorkEventArgs e)
{
ArrayList a = (ArrayList)e.Argument;
string[] fileNames = (string[])a[0];
this.loadMultiImages(fileNames);
}
private void loadMultiImages(string[] fileNames)
{
int i = 1;
int totalFiles = fileNames.Count();
foreach (string flName in fileNames)
{
if (!flName.Contains("Thumbs.db"))
{
Bitmap newBtmap = (Bitmap)Image.FromFile(flName);
FileInfo fi = new FileInfo(flName);
long l = fi.Length;
if (l > compressSize)
{
newBtmap = resizeImage(newBtmap, 1024,768) ;
newBtmap = saveJpeg(IMAGE_PATH + (SCANNING_NUMBER +
) + ".jpg", newBtmap, IMAGE_QUALITY);
}
else
{
File.Copy(flName, TEMP_IMAGE_PATH + (SCANNING_NUMBER + 1) + ".jpg");
}
if (!bgwLoading.CancellationPending)
{
CommonInformation.SCANNING_NUMBER++;
this.SafeInvoke(d => d.addItemToLvImageContainer(newBtmap));
bgwLoading.ReportProgress((int)Math.Round((double)i / (double)
(totalFiles) * 100));
i++;
}
}
}
}
}
public void addItemToLvImageContainer(Bitmap newBtmap)
{
imageList.Images.Add(newBtmap);
ListViewItem item;
item = new ListViewItem();
item.ImageIndex = SCANNING_NUMBER - 1;
item.Text = SCANNING_NUMBER.ToString();
lvImageContainer.Items.Add(item);
lvImageContainer.Items[item.ImageIndex].Focused = true;
}
为了找出错误,我将代码修改如下:
我已经注释了这两行
//newBtmap = resizeImage(newBtmap, 1024, 768);
// newBtmap = saveJpeg(IMAGE_PATH + scanning_number + ".jpg", newBtmap, Image_Quality );
并添加try-catch如下:
try
{
Bitmap newBtmap = (Bitmap)Image.FromFile(flName);
File.Copy(flName, CommonInformation.TEMP_IMAGE_PATH +
(CommonInformation.SCANNING_NUMBER + 1) + ".jpg");
if (!bgwLoading.CancellationPending)
{
this.SafeInvoke(d => d.imageList.Images.Add(newBtmap));
ListViewItem item;
item = new ListViewItem();
CommonInformation.SCANNING_NUMBER++;
item.ImageIndex = CommonInformation.SCANNING_NUMBER - 1;
item.Text = CommonInformation.SCANNING_NUMBER.ToString();
this.SafeInvoke(d => d.lvImageContainer.Items.Add(item));
bgwLoading.ReportProgress((int)Math.Round((double)i /
(double)(totalFiles) * 100));
this.safeInvoke(d=>d.addItemImageContainer(newBtmap))
catch (Exception ex)
{
MessageBox.Show( ex.Message);
}
加载一些图像后显示错误消息为“OutOfMemoryException”
以下行很可能会产生异常:
位图 newBtmap = (Bitmap)Image.FromFile(flName);
但图像文件没有损坏,文件扩展名为 .JPG。
如何解决这个问题?
【问题讨论】:
-
您能否在您的代码中添加一些日志记录,以表明它是否在特定图像或某个迭代中失败?即失败的总是相同的图像?另外,您对证明失败的 PC 之间的共同点有任何线索吗?我发现在某些情况下,在没有异常处理的线程下运行的控件会导致应用程序在没有通知的情况下中止。不经常发生,但必须经历几次。我通过在 safeinvoke 之前在 (additemtolv...) 和外部调用上添加异常处理解决了我的问题。
-
尽量不要多线程,看看问题是否消失。您描述的症状是线程同步的气味。发布运行的时间/优化与调试不同,因此您的代码可能运行不完全相同
-
@mr.kav 失败的不是同一张图片吗?有时我可以加载 30 张图片,有时可以加载 20 张图片,这是在一段不确定的时间之后发生的异常。
标签: c# image listview backgroundworker