好吧,事情已经到了这个地步。我在许多其他网站中搜索了这个网站,似乎没有人能给我一个直接的答案,所以我将尝试直接询问。在这个问题上呆了大约 3 天,我不能再浪费时间了。
目标:我正在构建的应用程序在 WPF 中,并将用作我的设计团队和我将很快开展的项目的错误跟踪器。由于我们将使用 C++ 构建游戏,因此发生的大多数错误都会对它们具有视觉元素,因此我包含了在用户将错误添加到列表时提供相关错误图像的功能。然后我拍摄该图像并将其保存到本地目录(用于测试)。现在,Error 对象中的图像路径指向了通向本地目录的路径。此功能已经过测试并且工作正常。当我想从列表中删除一个错误时,我的问题就出现了。我收到了那个非常臭名昭著的“IO Exception”,说我要删除的图像正在被另一个进程使用。
到目前为止:起初我尝试了非常优雅的解决方案,但是对于所有事情,您都只是想看看您是否可以让事情甚至工作。所以我现在使用的大部分代码都是实验性的和激进的。因此,请在查看时注意所使用的代码是出于绝望,因此可能已经尝试过任何“简单”的解决方案(我确实对此进行了很多研究,因为我讨厌这样做)。我能想到的事情是荒谬的处置和强制垃圾收集被调用,所以请不要评论这种做法的负面性质,我很清楚:)。
编码
将图像保存到本地目录
public void OnBrowseClick()
{
Microsoft.Win32.OpenFileDialog openBox = new Microsoft.Win32.OpenFileDialog();
// Show dialog box to user and grab output
Nullable<bool> result = openBox.ShowDialog();
if (result == true)
{
// Create temp variable to hold local path string
string localPath = Directory.GetCurrentDirectory();
// Grab the extension of the specified file path
string extension = openBox.FileName.Substring(openBox.FileName.LastIndexOf("\\"));
// Add extension to local path
localPath += extension;
// Create local copy of image at given file path (being ridiculous at this point)
using (Stream stream = new FileStream(openBox.FileName, FileMode.Open, FileAccess.ReadWrite))
{
using (Bitmap bmp = LoadImage(stream))
{
using (Bitmap temp = (Bitmap)bmp.Clone())
{
temp.Save(localPath);
temp.Dispose();
}
bmp.Dispose();
}
stream.Dispose();
}
// Set the URL in the image text box (UI stuff)
LocalError.ImagePath = localPath;
}
}
下面是上面函数中用到的LoadImage函数
private Bitmap LoadImage(Stream stream)
{
Bitmap retval = null;
using (Bitmap bitmap = new Bitmap(stream))
{
retval = new Bitmap(bitmap.Width, bitmap.Height, bitmap.PixelFormat);
using (Graphics gdi = Graphics.FromImage(retval))
{
gdi.DrawImageUnscaled(bitmap, 0, 0);
gdi.Flush();
gdi.Dispose();
bitmap.Dispose();
}
}
// Garbage collection here to be safe
GC.WaitForPendingFinalizers();
GC.Collect();
return retval;
}
最后我们来到我尝试删除图像的地方
public void OnDeleteClick()
{
// Ask user to make sure they want to delete selected item(s)
MessageBoxResult result = MessageBox.Show("Are you sure you want to delete selected item(s) from the list?",
"Delete", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
for( int i = 0; i < Parent.ErrorListControl.ErrorDataGrid.SelectedItems.Count; ++i)
{
// Get path to image
string path = (Parent.ErrorListControl.ErrorDataGrid.SelectedItems[i] as Error).ImagePath;
// Even tried calling garbage collection here!!!!!
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
File.Delete(path);
// Remove the error from the error list
Parent.ErrorListVM.ErrorList.Remove((Error)Parent.ErrorListControl.ErrorDataGrid.SelectedItems[i]);
// Decrement counter because we altered the list while in a loop
i--;
}
}
}
注意:如果有人希望我进一步解释任何事情,或者如果您需要知道我遗漏的内容,请询问我会尽快回复您!在这一点上,任何建议都是有帮助的,我绝对不知道我做错了什么。我通常只在 C++ 环境中编程,所以我倾向于管理我自己的内存,这整个“垃圾收集”的事情真的给我们的项目带来了麻烦!(题外话:我不知道为什么我没有得到任何颜色突出显示,所以我向任何花时间阅读本文的人道歉)。