Max*_*eng 7 c# writeablebitmap windows-phone-8
我有一个Windows Phone 8应用程序,它使用后台代理:
但是,当它在后台运行时,它会得到OutOfMemoryException一些故障排除:
OutOfMemoryException在期间抛出var bmp = new WriteableBitmap(480, 800);我试过DeviceStatus.ApplicationCurrentMemoryUsage用来跟踪内存使用情况:
- 限制是11,534,336(位)
- 当后台代理启动时,即使没有任何任务,内存使用量也变为4,648,960
- 从互联网获得更新时,它增长到5,079,040
- 完成后,它回落到4,648,960
- 当调用开始时(从用户控件生成图像),它增长到8,499,200
嗯,我想这就是问题所在,它几乎没有可用于渲染图像的内存WriteableBitmap.
知道如何解决这个问题吗?
有没有更好的方法从用户控件/或其他任何东西生成图像?
实际上原始图像可能只有100 kb左右,但是,在渲染时WriteableBitmap,文件大小(以及我猜想的所需内存大小)可能会增长到1-2MB.
或者我可以从任何地方释放内存吗?
================================================== ============
顺便说一下,当这个Code Project文章说我在周期性任务中只能使用11MB内存时;
但是,这篇MSDN文章说我可以使用Windows Phone 8 Update 3最多20 MB或25 MB; 哪个是对的?为什么我处于第一种情况?
================================================== ============
编辑:
说到调试器,它在MSDN文章中也有说明:
When running under the debugger, memory and timeout restrictions are suspended.
但为什么我仍然会遇到限制?
================================================== ============
编辑:
好吧,我发现似乎有些帮助,我现在就检查一下,建议仍然受欢迎.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下的XAML代码ImageUserControl:
<UserControl blabla... d:DesignHeight="800" d:DesignWidth="480">
<Grid x:Name="LayoutRoot">
<Image x:Name="nBackgroundSource" Stretch="UniformToFill"/>
//blabla...
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
C#代码背后ImageUserControl:
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) { }
}
Run Code Online (Sandbox Code Playgroud)
如果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...
}
Run Code Online (Sandbox Code Playgroud)
If I comment out the update progress, and create the image directly, it also works fine我认为你应该专注于那部分。似乎表明更新后某些内存未释放。在渲染图片之前,请确保更新过程中使用的所有引用都超出范围。强制垃圾收集也有帮助:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect(); // Frees the memory that was used by the finalizers
Run Code Online (Sandbox Code Playgroud)
另一件需要考虑的事情是调试器也使用大量内存。通过在“发布”模式下编译项目并在手机上部署来进行实际测试,以确保内存不足。
不过,我已经处于这种情况,所以我知道这可能还不够。要点是:.NET Framework 中的某些库是延迟加载的。例如,如果您的更新过程涉及下载一些数据,那么后台代理将加载网络库。这些库无法卸载,并且会浪费代理的一些内存。这就是为什么,即使释放更新过程中使用的所有内存,也无法恢复启动后台代理时所拥有的相同数量的可用内存。看到这一点,我在我的一个应用程序中所做的是将后台代理的工作负载跨越两次执行。基本上,当代理执行时:
这意味着图片每小时仅生成一次,而不是每 30 分钟生成一次,因此仅当其他一切都失败时才使用此解决方法。
| 归档时间: |
|
| 查看次数: |
1066 次 |
| 最近记录: |