我在用户控件中有一个OpenFileDialog
和PictureBox
。为了更好地理解这个问题,我将用几句话解释这个用户控件的工作原理。用户可以选择要为表单打开的图像。该图像的名称保存在数据库中,并且该图像的文件被复制到默认位置。当数据库中保存了一些图像时,当加载带有图片框控件的表单时,该图像就会加载到图片框中。如果用户选择另一个图像并想要使用新图像保存表单,我有一种方法可以小心地从我的默认位置删除旧图像文件,这就是问题发生的地方。
当我加载图像并尝试保存新图像时,有时(实际上非常罕见)我会收到一条错误消息,资源正在被另一个进程使用..
我可以粘贴确切的错误如果需要的话。我认为问题是由图片框及其处理图像的方式引起的。
这是我的代码:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if (MyImage != null)
{
MyImage.Dispose();
}
selectedFile = openFileDialog1.FileName;
selectedFileName = openFileDialog1.SafeFileName;
MyImage = new Bitmap(openFileDialog1.FileName);
pictureBox1.Image = (Image)MyImage;
int imageWidth = pictureBox1.Image.Width;
int picBoxWidth = pictureBox1.Width;
if (imageWidth != 0 && picBoxWidth > imageWidth)
{
pictureBox1.Width = imageWidth;
}
else
{
pictureBox1.Width = defaultPicBoxWidth;
}
}
catch (Exception ex)
{
logger.Error(ex.ToString());
MessageBox.Show("Error loading image!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
以及我的删除方法:
public void DeleteImage(AppConfig imageInfo, string imageName)
{
string imgPath = imageInfo.ConfigValue.ToString();
try
{
File.Delete(imgPath + "\\" + imageName);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
我认为:
if (MyImage != null)
{
MyImage.Dispose();
}
会处理这个问题,但有时仍然会发生。而且因为并非每次都如此,所以处理它就更加重要,因为在某些时候我可能会决定我已经解决了它,但事实上只是在一段时间内很幸运。
最佳答案
MyImage = new Bitmap(openFileDialog1.FileName);
pictureBox1.Image = (Image)MyImage;
是的,该代码会锁定文件。该锁是由 GDI+ 创建的内存映射文件对象生成的,该对象可以有效地将文件的像素数据映射到内存中,而无需在分页文件中分配空间。只要图像显示在图片框中并且未被处理,您就无法删除该文件,锁定可以防止这种情况。您必须先处理该图像并将 Image 属性设置回 null,然后才能删除该文件。
您可以通过在内存中复制图像来防止文件被锁定:
using (var temp = new Bitmap(openFileDialog1.FileName)) {
pictureBox1.Image = new Bitmap(temp);
}
当然,如果图像很大,就应该避免这样做。并且请注意,另一个进程实际上可能对该文件有类似的锁定。你对此无能为力。
关于c# - .NET PictureBox - 如何确保资源已释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15274463/