我有一個列表(簡單列表框),其中包含主 - 從基礎上的圖片(如果用戶單擊列表項目,則打開詳細信息頁面)。我遇到了相當有名的圖像內存泄漏問題,描述爲here,here,here和here。帶有自動內存清理功能的圖片下載器
一種可能的方式是當導航從and clean them時run through all images。
在one of the threads,我發現更有趣的解決方案:它自動清理圖像,但這不適用於虛擬化(圖像丟失或混合,如果要添加私人字段來存儲ImageSource)。建議的修復方法是添加依賴項屬性。
但是我仍然面臨着同樣的問題:圖像在向下滾動並返回後混合起來。看起來像依賴屬性隨機更改,但我不能趕上他們正在改變的時刻。
public class SafePicture : ContentControl
{
public static readonly DependencyProperty SafePathProperty =
DependencyProperty.RegisterAttached(
"SafePath",
typeof(string),
typeof(SafePicture),
new PropertyMetadata(OnSourceWithCustomRefererChanged));
public string SafePath
{
get { return (string)GetValue(SafePathProperty); }
set { SetValue(SafePathProperty, value); }
}
private static void OnSourceWithCustomRefererChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null) // New value here
return;
}
public SafePicture()
{
Content = new Image();
Loaded += OnLoaded;
Unloaded += OnUnloaded;
}
private void OnLoaded(object _sender, RoutedEventArgs _routedEventArgs)
{
var image = Content as Image;
if (image == null)
return;
var path = (string)GetValue(SafePathProperty); // Also, tried SafePath (debugger cant catch setter and getter calls), but same result.
image.Source = null;
{
var request = WebRequest.Create(path) as HttpWebRequest;
request.AllowReadStreamBuffering = true;
request.BeginGetResponse(result =>
{
try
{
Stream imageStream = request.EndGetResponse(result).GetResponseStream();
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
if (imageStream == null)
{
image.Source = new BitmapImage { UriSource = new Uri(path, UriKind.Relative) };
return;
}
var bitmapImage = new BitmapImage();
bitmapImage.CreateOptions = BitmapCreateOptions.BackgroundCreation;
bitmapImage.SetSource(imageStream);
image.Source = bitmapImage;
});
}
catch (WebException)
{
}
}, null);
}
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
var image = Content as Image;
if (image == null)
return;
var bitmapImage = image.Source as BitmapImage;
if (bitmapImage != null)
bitmapImage.UriSource = null;
image.Source = null;
}
}
用法:
<wpExtensions:SafePicture SafePath="{Binding ImageUrl}"/>
所以,乍一看,它工作正常,但如果向下滾動,並返回後,圖像的隨機變化。編輯:在這種情況下,現在,我只使用純ListBox,沒有虛擬化(但期望它在其他情況下)。
EDIT2:重現此問題的示例項目。我相信,它會在一段時間內包含解決方案:https://simca.codeplex.com/
感謝您的幫助!我希望,我可以給你發一杯啤酒:)。但是,問題仍然存在。 (path!= SafePath)在BeginGetResponse()後導致訪問異常。和圖像仍然混淆(即使在路徑檢查調度) –
無論如何,謝謝你突出的原因。另一個問題:我在SafePath的getter/setter中添加了斷點,但是調試器永遠不會停在那裏。另外,實際上,這是最簡單的情況:即使沒有虛擬化(除非有一些內部的),我也將它用於常見的ListBox。 –
上傳示例項目。 –