我在应用程序的 Suspending 事件中保存了 RenderTargetBitmap。如果我打开应用程序并在 Visual Studio 中点击“暂停和关闭”,一切都很好。但是,如果我先进入“开始”屏幕或打开另一个应用程序并等待一段时间,换句话说 - 该应用程序不在前台,则 RenderTargetBitmap.GetPixelsAsync() 方法会抛出此 COMException,并带有 HResult 0x80004005 和“未指定错误”描述。考虑到在实际使用中,当用户从应用程序切换到其他应用程序时会发生暂停,这个错误几乎总是会发生。我正在明确保存的 RenderTargetBitmap 在这一点上不为空,因为我确实检查了这一点。
另外我在开发过程中注意到,有时当我从应用程序切换到其他应用程序然后返回时,即使应用程序没有暂停并立即打开,一些图片也不会出现在 UI 中,就好像它们已被垃圾收集一样。考虑到仍然有引用,这很奇怪。不确定它是否与上述问题有关,但似乎可以。
有没有人遇到过类似的问题?当应用离开屏幕时,这些图像究竟会发生什么?
编辑:
这是一个例子。xml:
<Grid x:Name="RootGrid" Background="AntiqueWhite">
<Rectangle Width="40" Height="50" Fill="Blue"/>
<Rectangle Width="70" Height="50" Fill="Red" Margin="100 300 0 0"/>
<Rectangle Width="30" Height="60" Fill="Green" Margin="0 0 150 70"/>
<Button x:Name="RenderButton" VerticalAlignment="Top" HorizontalAlignment="Center"
Margin="0 20 0 0" Content="Render" Click="RenderButton_OnClick"/>
</Grid>
后面的代码:
private RenderTargetBitmap renderTargetBitmap;
public MainPage()
{
InitializeComponent();
Application.Current.Suspending += CurrentOnSuspending;
}
private async void RenderButton_OnClick(object sender, RoutedEventArgs args)
{
this.renderTargetBitmap = new RenderTargetBitmap();
await this.renderTargetBitmap.RenderAsync(RootGrid);
}
private async void CurrentOnSuspending(object sender, SuspendingEventArgs args)
{
var defferal = args.SuspendingOperation.GetDeferral();
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"render.png", CreationCollisionOption.ReplaceExisting);
await SaveToFileAsync(this.renderTargetBitmap, file);
defferal.Complete();
}
private async Task SaveToFileAsync(RenderTargetBitmap image, IStorageFile file)
{
using (var stream = await file.OpenStreamForWriteAsync())
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream.AsRandomAccessStream());
var pixels = await image.GetPixelsAsync();
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)image.PixelWidth, (uint)image.PixelHeight, 96, 96, pixels.ToArray());
await encoder.FlushAsync();
}
}
在移动设备上启动应用程序,单击“渲染”按钮。之后按开始将应用程序关闭屏幕,等待一段时间(10 秒即可),然后在 Visual Studio 的调试位置栏中按“暂停和关闭”。观察 COMException。