我在WPF中有一个非常图像密集型的应用程序。我尽可能以最好的方式管理记忆,但图像正在推动我超出预算。它们只是在某个点停止渲染,然后应用程序崩溃。我将图像控件的源绑定到给定路径。
<Image Source="{Binding ImagePath, Mode=OneWay}"/>
有没有更好的方法来解决这个问题?也许我可以关闭缓存?我知道问题出在图像上,因为当我停止显示图像时,问题就会消失。
答案 0 :(得分:0)
我认为我的问题是图像被不必要地重新创建。我不知道怎么做。我不知道为什么。当我创建自己的缓存服务并使用BitmapImage
而不是路径时,内存问题就消失了。我甚至可以看到它被包含在转换器中,该转换器采用路径并生成缓存的BitmapImage
。这不太理想。它只能摆脱重复。我仍然需要玩到期,但我很高兴这是一个解决方案。
public class ImageCachingSystem : IImageCachingSystem
{
private readonly DispatcherTimer _timer = new DispatcherTimer();
private readonly object l_cachesByName = new object();
private readonly Dictionary<String, ImageCache> _cachesByName = new Dictionary<String, ImageCache>();
public ImageCachingSystem()
{
_timer.Interval = TimeSpan.FromSeconds(10);
_timer.Tick += OnTick;
_timer.Start();
}
public BitmapImage GetImage(String a_path)
{
return GetImage(new Uri(a_path));
}
public BitmapImage GetImage(Uri a_url)
{
lock (l_cachesByName)
{
var path = a_url.ToString().ToLower();
if (_cachesByName.ContainsKey(path))
{
return _cachesByName[path].Image;
}
else
{
var image = new BitmapImage(a_url);
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.Freeze();
_cachesByName[path] = new ImageCache
{
Expiration = DateTime.Now + TimeSpan.FromMinutes(30),
Path = path,
Image = image,
};
return image;
}
}
}
private void OnTick(object sender, EventArgs e)
{
lock (l_cachesByName)
{
var expired = _cachesByName.Where(i => i.Value.Expiration < DateTime.Now).Select(i => i.Key);
foreach (var key in expired.ToArray())
_cachesByName.Remove(key);
}
}
class ImageCache
{
public String Path { get; set; }
public DateTime Expiration { get; set; }
public BitmapImage Image { get; set; }
}
}