さて、これになりました。私はこのウェブサイトを他の多くのサイトで検索しましたが、誰も私に正直な答えを与えることができないように思われるので、私はただ率直に尋ねてみるつもりです。この問題に約3日間携わっていますが、これ以上時間を無駄にするわけにはいきません。
目標:私が構築しているアプリはWPFにあり、私の設計チームのプロジェクトのバグトラッカーとして使用される予定であり、まもなく着手します。C ++でゲームを構築するので、発生するエラーのほとんどは視覚的な要素を持っているので、ユーザーがリストにバグを追加したときに問題のエラーのイメージを提供する機能を含めました。次に、そのイメージを取得して、ローカルディレクトリに保存します(テスト用)。これで、Errorオブジェクトのイメージパスは、ローカルディレクトリにつながるパスを指します。この機能はテスト済みで、正常に動作します。リストからバグを削除したいときに問題が発生します。削除したい画像が別のプロセスで使用されているという非常に悪名高い「IO例外」が発生しています。
これまでのところ:最初は非常に洗練されたソリューションを試しましたが、他のすべての場合と同様に、まったく機能するかどうかを確認したいところまで来ています。ですから、私が使用しているコードのほとんどが実験的で過激なものになっています。ですから、それを見るときは、使用されているコードが絶望的ではないことに注意してください。したがって、「単純な」解決策はおそらくすでに試されています(これを行うのは嫌なので、私はこれをたくさん研究しました)。私が頭の中で考えることができるのは、不条理な量の廃棄と強制的なガベージコレクションが呼び出されていることです。したがって、この慣行の否定的な性質についてコメントしないでください。私はよく知っています:)。
コード
画像をローカルディレクトリに保存しています
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 ++環境でのみプログラミングするので、自分のメモリを管理する傾向があります。この「ガベージコレクション」全体が、プロジェクトに大きな影響を及ぼしています。(オフトピックノート:なぜ色が強調表示されないのかわからないので、これを読むのに時間を割いてくださった方にはお詫び申し上げます)。