2015-02-06 49 views
2

我正面臨內存泄漏問題。泄漏來自這裏:如何處理BitmapImage緩存?

public static BitmapSource BitmapImageFromFile(string filepath) 
{ 
    BitmapImage bi = new BitmapImage(); 

    bi.BeginInit(); 
    bi.CacheOption = BitmapCacheOption.OnLoad; //here 
    bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache; //and here 
    bi.UriSource = new Uri(filepath, UriKind.RelativeOrAbsolute); 
    bi.EndInit(); 

    return bi; 
} 

我有一個ScatterViewItem,其中包含一個Image,源是這個函數的BitmapImage

實際的事情比這更復雜,所以我不能簡單地把一個圖像放入它。我也無法使用默認加載選項,因爲圖像文件可能會被刪除,因此在刪除過程中會遇到一些訪問文件的權限問題。

當我關閉ScatterViewItem時,會發生問題,然後關閉Image。但是,高速緩存的內存未被清除。所以在很多週期之後,內存消耗非常大。

我在Unloaded函數中嘗試設置image.Source=null,但它沒有清除它。

如何在卸載過程中正確清除內存?

+0

這可能對你有用[什麼是在C#中釋放內存的正確方法](http://stackoverflow.com/questions/6066200/what-is-the-correct-way-to-free-memory -in-c-sharp) – Izzy 2015-02-06 11:19:51

+1

謝謝,但可悲的是GC沒有收集到它。直接調用GC.Collect()也不會收集它。 – 2015-02-06 11:25:55

回答

2

我找到了答案here。似乎它是WPF中的一個錯誤。

我修改的功能包括Freeze

public static BitmapSource BitmapImageFromFile(string filepath) 
{ 
    var bi = new BitmapImage(); 

    using (var fs = new FileStream(filepath, FileMode.Open)) 
    { 
     bi.BeginInit();     
     bi.StreamSource = fs;     
     bi.CacheOption = BitmapCacheOption.OnLoad; 
     bi.EndInit(); 
    } 

    bi.Freeze(); //Important to freeze it, otherwise it will still have minor leaks 

    return bi; 
} 

我還創建自己的關閉功能,這將被稱爲前我關閉ScatterViewItem

public void Close() 
{ 
    myImage.Source = null; 
    UpdateLayout(); 
    GC.Collect(); 
} 

因爲myImage在託管ScatterViewItemGC.Collect()必須在父項關閉之前調用。否則,它仍會在內存中徘徊。