为什么我的图像有时会在简历上重新加载(和WriteableBitmap消失)?

时间:2013-01-21 06:26:43

标签: winrt-xaml writeablebitmap

当我恢复我的应用时,有时它会丢失图像。我甚至可以在简单的应用程序中重现这一点。

这表现在两种不同的方式,取决于图像的来源:

  • 如果我执行类似<Image Source="/Assets/Logo.png"/>的操作(即,通过URI从我的应用包中加载图像),图像将短暂消失,然后重新加载。当屏幕包含许多图像时,这更容易看到;它们按顺序重新加载,因此我可以在屏幕上观看图像加载波动。
  • 如果我创建了一个WriteableBitmap并将其绑定到Image.Source,那么位图将完全消失,永远不会返回。

如果它只是重​​新加载图像(虽然涟漪效果令人不愉快),我可能会忍受这种情况,但我做了很多动态图像生成,并且我的所有WriteableBitmaps都消失了。

每次应用程序暂停和恢复时都不会发生这种情况,有时只会发生。我没有找到一个可靠的repro案例,但似乎暂停的时间越长,我在临时工作中做的事情就越多(在桌面Chrome上浏览网页,玩全屏DirectX游戏,如TapTiles和Microsoft Minesweeper) ,更有可能的是,当我切换回我的应用程序时,图像将会丢失。 (该应用终止并重新启动 - 它仍然是相同的应用实例。)

我想知道这是否与从视频内存刷新的图像有关。但我不知道如何测试这个假设,所以在这一点上它只是猜测。

到目前为止,我还没有找到任何方法让我的程序甚至告诉WriteableBitmaps丢失。事件序列与正常暂停和恢复相同:

  • Window.Current.Activated fires with args.WindowActivationState == Deactivated
  • Window.Current.VisibilityChanged使用args.Visible == false
  • 触发
  • Application.Suspending fires
  • (时间过去了)
  • Application.Resuming fires
  • Window.Current.VisibilityChanged使用args.Visible激活== true
  • Window.Current.Activated fires with args.WindowActivationState == CodeActivated

我没有任何运气找到“顺便说一下,你所有的图像都消失了”事件。 WriteableBitmap没有任何事件。 Image有ImageOpened和ImageFailed事件,但是当我从URI加载图像时它们才会触发 - 当Source是WriteableBitmap时它们永远不会触发。

我已经能够在琐碎的应用程序中重现这一点,因此它不是由某些第三方库引起的。带有由URI加载的图像的空白页面将再次触发ImageOpened(如果应用程序已暂停一段时间,然后您将其恢复,则图像将在完成重新加载之前短暂闪烁)。如果应用程序已暂停一段时间,然后您将其恢复,则将初始化为WriteableBitmap的图像的空白页面将消失。

如何修复WriteableBitmaps(以及可能的内容-URI图像)的丢失?有什么方法可以防止图像丢失?如果没有,有什么方法可以检测到它们已经丢失了,所以我可以重新创建我的WriteableBitmaps吗?

(对于奖励积分,我很想知道为什么图像会消失,但那部分完全是可选的。我很久以来就放弃了期待WinRT有意义。)

2 个答案:

答案 0 :(得分:2)

我做了一些实验,明确表示WinRT只是丢失了WriteableBitmap的内容,而不是WriteableBitmap本身。 WriteableBitmap实例仍然可行;如果你给它新的像素数据,它工作正常。只是有时候,在app简历中,它的内容会被一堆透明像素所取代。

我已经能够通过挂钩我的应用程序的OnResuming事件来解决这个问题,并使用该事件来获取我的WriteableBitmap的PixelBuffer.AsStream(),写入新的像素,然后调用WriteableBitmap.Invalidate()。如果重新生成图像的代码是同步的,那么当应用程序恢复时,图像甚至不会闪烁。

我怀疑普通的位图(通过源URI加载)也会丢失它们的像素缓冲区,并且在应用程序恢复后不得不重新加载它们的像素。图像加载是异步的,这解释了在内容重新出现之前的延迟/闪烁。

我还没有找到方法来了解图像是否丢失了像素(尽管显然URI加载的图像有一些知道的方式,因为它们会自动重新加载)。因此,使用WriteableBitmaps,最安全的事情似乎是始终在应用简历上重新填充它们。

答案 1 :(得分:1)

为了取代之前的答案,我发现只需使WriteableBitmap无效即可。我会主张在重写图像之前先尝试一下,因为这可能会对您的应用程序产生更大的影响,而不仅仅是对它进行无效化。

此错误也可以通过强制您的应用程序暂停和恢复来重现。当我们等待应用程序暂停时,我们最初很难确定它何时发生。 This is a link一篇关于如何在WinRT应用程序中模拟Suspend和Resume的文章。