【发布时间】:2016-07-27 23:07:17
【问题描述】:
我在一个 WPF 应用程序中工作,我在两个地方显示我的图像,这意味着在两个地方加载了相同的图像。在其中一个地方,图像将与其他几张图像一起显示在滑块中,可以在其中编辑和保存。如果该位置没有可用的图像,我应该显示一个单独的图像 Image not found 这是不可编辑的。
当我开始使用该功能时,我在编辑和保存期间遇到了被另一个进程使用的异常。因此,在搜索之后,我想出了一个解决方案,现在当我单击“下一个”或“上一个”或“第一个或最后一个”滑块时,很少会出现内存不足异常。滑块只是一个带有 4 个按钮的图像控件。单击按钮时,将调用以下方法。我不确定是否有任何内存泄漏。
bool NoImage = true;
private static readonly object _syncRoot = new object();
private BitmapSource LoadImage(string path)
{
lock (_syncRoot) //lock the object so it doesn't get executed more than once at a time.
{
BitmapDecoder decoder = null;
try
{
//If the image is not found in the folder, then show the image not found.
if (!File.Exists(path) && (path != null))
{
System.Drawing.Bitmap ss = XXXX.Resources.ImageNotFound;
var stream = new System.IO.MemoryStream();
if (!File.Exists(Path.GetTempPath() + "ImageNotFound.jpg"))
{
FileStream file = new FileStream(Path.GetTempPath() + "ImageNotFound.jpg", FileMode.Create, FileAccess.Write);
ss.Save(stream, ImageFormat.Jpeg);
stream.Position = 0;
stream.WriteTo(file);
file.Close();
stream.Close();
}
path = Path.Combine(Path.GetTempPath(), "ImageNotFound.jpg");
NoImage = false;
}
else
{
if (!EnableForEdit)
NoImage = false;
else
NoImage = true;
}
if (!string.IsNullOrEmpty(path) && (!NoImage || File.Exists(path)))
{
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
return decoder.Frames.FirstOrDefault();
}
else
return null;
}
catch (OutOfMemoryException ex)
{
MessageBox.Show("Insufficient memory to handle the process. Please try again later.", "Application alert");
return null;
}
catch (Exception ex)
{
// Error handling.
throw new ApplicationException(ex.Message);
}
finally
{
decoder = null;
GC.WaitForFullGCComplete(1000);
GC.Collect(0, GCCollectionMode.Forced);
}
}
}
<Image x:Name="viewImage" Grid.Row="2" Height="100" Width="135" Source="{Binding DisplayImage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" />
如果我的方法有误,请告诉我应该在哪里进行更改,或者是否有更简单的方法可以做。请帮忙。
注意:加载的图片大于5Mb
【问题讨论】:
-
我建议的第一件事是转向延迟加载,也可以通过将它们包装在 using 语句中来处理您的流
-
The images which are loaded is above 5Mb- 大约 5MB 或者也可能是 500MB(也超过 5mb)? -
我还建议使用绑定而不是后面的代码,当您指定绑定值时,如果您将其中一个或两个设置为预定义的值,则绑定会为您提供 2 个备用值选项(FallbackValue 和 TargetNullValue)未找到图片资源,那么大部分工作已为您完成
-
_syncRoot也是静态变量还是实例变量?如果它的实例是一次加载该类的多个实例,还是该类仅加载了 1x。 -
@MikeT 在滑块中延迟加载意味着什么?
_synRoot用于有时用户太快而无法向上滑动图像。在第二个按钮上多次点击。为此更新了问题。
标签: c# wpf memory-leaks out-of-memory