7

我用来从资源StreamResourceInfo.Stream中获取s 。使用后和流BitmapImage正确吗?我问是因为在内存分析器中,如果我这样做会出错。内存分析器表示已处置的实例尚未被 GC。 CloseDispose

如果我在网上看,我只能找到这个主题的帖子。在这篇文章中,回复者说,处置是有意义的。但是,如果我看情况和效果,我认为这是不对的。有人知道什么是正确的行动吗?
附加信息:在我看到的 msdn 示例中,它们没有 Dispose 或 Close。

编辑
感谢 Rick Sladkeys 的回答,我找到了解决方案:我分配StreamResourceInfo.Stream给. 在msdn中是这样写的:StreamSourceBitmapImage

如果您希望在创建 BitmapImage 后关闭流,请将 CacheOption 属性设置为 BitmapCacheOption.OnLoad。默认的 OnDemand 缓存选项保留对流的访问,直到需要位图,并且清理由垃圾收集器处理。

这意味着,BitmapImage获取流的所有权。这就是为什么如果我手动关闭/处理流,内存分析器会显示错误:位图将持有对流的引用(BitmapCacheOption OnDemand),因此只要 BitmapImage 有效,GC 就不会释放它,但流已经明确处置。在这个特定的例子中,处理是一个坏主意。
为了完整起见,我还在 msdn 中查看了上面TextRange.Load调用链接的示例。对于Load,它是相反的,Load不占用所有权,因此流必须在完成后关闭/处置。

4

1 回答 1

11

混乱,我同意它令人困惑,来自流所有权的微妙但关键的概念。在 MSDN 示例中,您可以将它们视为“看,不Dispose,不Close,所以我不应该那样做?”

但简单的答案是必须有人负责关闭流。您可能正在调用的 API:

  • Application.GetResourceStream

返回一个StreamResourceInfo流和 URL 的原始容器。显然,StreamResourceInfo不拥有该流。所以当你打电话给你时,Application.GetResourceStream 现在拥有其中包含的流StreamResourceInfo,如果你没有对它做任何其他事情,你将负责关闭它。API 通过将流的Application所有权作为值返回给我们,从而将流的所有权从自身转移给我们。

现在,当您流传递给另一个实体时,就会出现令人困惑的部分。我们以 MSDN 为例:

// Navigate to xaml page
Uri uri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetResourceStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;

现在在这个例子中没有Dispose和没有Close。但是所有权从我们(调用者)转移到了XamlReader实例。流不再是我们的责任;我们已将所有权转让给其他人。事实上,当它完成流时XamlReader会调用。Close一个谜团解开了。

之所以如此成问题,是因为所有权的概念通常隐含在文档中,我们应该“弄清楚”。希望只是重新审视所有权的概念以及它是可转让的事实将使人们更容易感到舒适,而不是Close像新所有者那样使用安全。即使他们不这样做,这也不再是我们的问题了!

于 2011-05-27T03:26:25.400 回答