yr_*_*eng 9 c# out-of-memory bitmapimage windows-phone-8
我正在测试一个WP8应用程序和它的图像查看器来显示许多图像,我发现应用程序的内存消耗正在提高,并希望找到如何解决它.
我已经从网上阅读了一些文章,但这些文章提供的解决方案不适用于我的应用,请阅读以下历史记录.
首先,我发现文章" Windows Phone 7的图像提示 "并下载其样本进行清洁图像缓存测试,它使用的是1张图像.
然后出于测试目的,我使用应用程序内的15个离线图像编译此应用程序,并设置为"内容",请从此处下载测试应用程序.
我的测试步骤是:
(1) Launch app
(2) Go to Image Caching page
(3) Enable checkbox "Avoid Image Caching"
(4) Continuously tapping button Show/Clear
(5) Keep watching the memory status textblock at the bottom
Run Code Online (Sandbox Code Playgroud)
当我测试我的应用程序时,内存正在提升,如16.02MB =>显示(19.32MB)=>清除(16.15MB)=>显示(20.18MB)=>清除(17.03MB)...等和内存即使离开缓存页面再次进入缓存页面也不会被释放.似乎文章" Windows Phone 7的图像提示 "的解决方案仅适用于1个图像.
这是" Windows Phone 7的图像提示 "解决方案的xaml和代码隐藏.
[Caching.xaml]
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<ToggleButton Content="Show" Width="150" Checked="ShowImageClicked" Unchecked="ClearImageClicked"/>
<CheckBox x:Name="cbAvoidCache" Content="Avoid Image Caching"/>
</StackPanel>
<Image x:Name="img" Grid.Row="2" Width="256" Height="192"/>
<TextBlock x:Name="tbMemory" Grid.Row="2" Text="Memory: " VerticalAlignment="Bottom" Style="{StaticResource PhoneTextLargeStyle}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)
[Caching.xaml.cs]
public partial class Caching : PhoneApplicationPage
{
public Caching()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Start();
timer.Tick += delegate
{
GC.Collect();
tbMemory.Text = string.Format("Memory: {0} bytes", DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"));
};
}
private int nIndex = 1;
BitmapImage bitmapImageFromUri = new BitmapImage();
private void ShowImageClicked(object sender, RoutedEventArgs e)
{
string strImage = string.Format("../ImagesAsContent/{0:D2}.jpg", nIndex);
bitmapImageFromUri.UriSource = new Uri(strImage, UriKind.Relative);
img.Source = bitmapImageFromUri;
nIndex++;
if (nIndex > 15)
{
nIndex = 1;
}
(sender as ToggleButton).Content = "Clear";
}
private void ClearImageClicked(object sender, RoutedEventArgs e)
{
if (cbAvoidCache.IsChecked == true)
{
// set the UriSource to null in order to delete the image cache
BitmapImage bitmapImageFromUri = img.Source as BitmapImage;
bitmapImageFromUri.UriSource = null;
}
img.Source = null;
(sender as ToggleButton).Content = "Show";
}
}
Run Code Online (Sandbox Code Playgroud)
我也尝试搜索任何其他解决方案,一些测试结果如下.
(1)文章" [wpdev] BitmapImage内存泄漏 ":它提供了2个解决方案,一个是DisposeImage API,另一个是将BitmapImage源设置为null,如下所示.另外文章让我们知道我们必须小心事件处理程序附加/分离,但是我的测试应用程序在缓存页面中没有事件处理程序.
[DisposeImage]
private void DisposeImage(BitmapImage image)
{
if (image != null)
{
try
{
using (var ms = new MemoryStream(new byte[] { 0x0 }))
{
image.SetSource(ms);
}
}
catch (Exception)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
[设为null]
BitmapImage bitmapImage = image.Source as BitmapImage;
bitmapImage.UriSource = null;
image.Source = null;
Run Code Online (Sandbox Code Playgroud)
(2)文章" Windows phone:带有图像内存不足的列表框 ":它提供了一个API"DisposeImage",与下面的(1)相比差别不大,但是这也行不通,我还是得到了内存提高症状.
public static void DisposeImage(BitmapImage image)
{
Uri uri= new Uri("oneXone.png", UriKind.Relative);
StreamResourceInfo sr=Application.GetResourceStream(uri);
try
{
using (Stream stream=sr.Stream)
{
image.DecodePixelWidth=1; //This is essential!
image.SetSource(stream);
}
}
catch
{}
}
Run Code Online (Sandbox Code Playgroud)
(3)文章" 找不到内存泄漏 ":它提供了与上述相同的2个解决方案,也提到了孤立存储图像无法重现的问题,但是我的测试应用程序的图像来自隔离存储.
(4)我还尝试了1000张图片,当应用程序依次显示190张图片时,测试结果是应用程序崩溃,请参阅下面的Windows Phone Application Analysis Graphics获取内存.

最后,感谢您耐心阅读我的问题和历史,我一直在努力寻找解决方案多天.如果您有任何线索或解决方案,请告诉我.
谢谢.
小智 3
我正在处理同样的问题,我认为,最终,实际上我找到了解决方法,我不是专业程序员,但这是我的解决方案:
public Task ReleaseSingleImageMemoryTask(MyImage myImage, object control)
{
Pivot myPivot = control as Pivot;
Task t = Task.Factory.StartNew(() =>
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (myImage.img.UriSource != null)
{
myImage.img.UriSource = null;
DisposeImage(myImage.img);
}
PivotItem it = (PivotItem)(myPivot.ItemContainerGenerator.ContainerFromIndex(myImage.number % 10));
Image img = FindFirstElementInVisualTree<Image>(it);
if (img != null)
{
img.Source = null;
GC.Collect();
}
});
myImage.released = true;
});
return t;
}
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
{
return (T)child;
}
else
{
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
private void DisposeImage(BitmapImage img)
{
if (img != null)
{
try
{
using (var ms = new MemoryStream(new byte[] { 0x0 }))
{
img = new BitmapImage();
img.SetSource(ms);
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("ImageDispose FAILED " + e.Message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助:)
| 归档时间: |
|
| 查看次数: |
7402 次 |
| 最近记录: |