- 从互联网获取数据;
- 基于使用步骤1中的数据作为数据源的用户控件生成图像;
- 在用户控件中,我有Grid和StackPanel以及一些文本和图像控件;
- 当一些图像使用安装文件夹(/Assets/images/...)中的本地资源时,其中一个被用户从手机相册库中选择作为背景,因此我必须使用C#代码设置其源。
OutOfMemoryException
错误,目前进行了一些故障排除。
- 当我在前台运行进程时,一切正常;
- 如果我注释掉更新进度,并直接创建图像,也能正常工作;
- 如果我不设置背景图片,也能正常工作;
OutOfMemoryException
是在var bmp = new WriteableBitmap(480, 800);
期间抛出的。
我已经将图像大小从1280*768缩小到了800*480,我认为这是全屏背景图像的底线,不是吗?- 经过一些研究,我发现这个问题是因为超过了周期任务的11MB限制而出现的。
我尝试使用
DeviceStatus.ApplicationCurrentMemoryUsage
来跟踪内存使用情况:-- 限制为11,534,336(位)
-- 当后台代理启动时,即使没有任何任务,内存使用情况也会变为4,648,960
-- 当从互联网获取更新时,它增加到5,079,040
-- 完成后,它又降回到4,648,960
-- 当调用开始(从用户控件生成图像)时,它增加到8,499,200
我猜那就是问题所在,内存太少了,无法通过WriteableBitmap
渲染图像。
有什么办法可以解决这个问题吗?
有没有更好的方法从用户控件或其他任何地方生成图像?
实际上,原始图像可能只有100KB左右,但是当通过WriteableBitmap
渲染时,文件大小(以及所需内存大小)可能增加到1-2MB。
或者我可以从哪里释放内存?
==============================================================
顺便提一下,当这篇Code Project article说我只能在定期任务中使用11MB内存时;
然而,这篇MSDN article说我可以使用高达20 MB或25MB(使用Windows Phone 8 Update 3)的内存; 哪个是正确的?为什么我处于第一种情况?
==============================================================
编辑:
说到调试器,MSDN文章中也提到了:
在调试器下运行时,内存和超时限制被暂停。
但为什么我仍然会遇到限制呢?
==============================================================
编辑:
好的,我找到了一些似乎有用的东西,现在我会检查它们,但仍然欢迎建议。
http://writeablebitmapex.codeplex.com/
http://suchan.cz/2012/07/pro-live-tiles-for-windows-phone/
http://notebookheavy.com/2011/12/06/microsoft-style-dynamic-tiles-for-windows-phone-mango/
==============================================================
生成图像的代码:Deployment.Current.Dispatcher.BeginInvoke(() =>
{
var customBG = new ImageUserControl();
customBG.Measure(new Size(480, 800));
var bmp = new WriteableBitmap(480, 800); //Thrown the **OutOfMemoryException**
bmp.Render(customBG, null);
bmp.Invalidate();
using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
{
filename = "/Shared/NewBackGround.jpg";
using (var stream = isf.OpenFile(filename, System.IO.FileMode.OpenOrCreate))
{
bmp.SaveJpeg(stream, 480, 800, 0, 100);
}
}
}
ImageUserControl
的XAML代码:
<UserControl blabla... d:DesignHeight="800" d:DesignWidth="480">
<Grid x:Name="LayoutRoot">
<Image x:Name="nBackgroundSource" Stretch="UniformToFill"/>
//blabla...
</Grid>
</UserControl>
ImageUserControl
的C#代码如下:
public ImageUserControl()
{
InitializeComponent();
LupdateUI();
}
public void LupdateUI()
{
DataInfo _dataInfo = new DataInfo();
LayoutRoot.DataContext = _dataInfo;
try
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var isoFileStream = isoStore.OpenFile("/Shared/BackgroundImage.jpg", FileMode.Open, FileAccess.Read))
{
BitmapImage bi = new BitmapImage();
bi.SetSource(isoFileStream);
nBackgroundSource.Source = bi;
}
}
}
catch (Exception) { }
}
当
DataInfo
是 设置页面 中的另一个类,它保存从互联网获取的数据时:public class DataInfo
{
public string Wind1 { get { return GetValueOrDefault<string>("Wind1", "N/A"); } set { if (AddOrUpdateValue("Wind1", value)) { Save(); } } }
public string Wind2 { get { return GetValueOrDefault<string>("Wind2", "N/A"); } set { if (AddOrUpdateValue("Wind2", value)) { Save(); } } }
//blabla...
}