处置 StreamResourceInfo.Stream
我使用 StreamResourceInfo.Stream 从资源中获取 BitmapImage 。使用流后 Close
和 Dispose
是否正确? 我问这个问题是因为在内存分析器中,如果这样做我会收到错误。内存分析器表示已处置的实例尚未进行 GC。
如果我在网上查看,我只能找到 此帖子针对此主题。在这篇文章中,回复者说,处理是有意义的。但从当时的情况和效果来看,我认为这是不对的。有人知道什么是正确的行动吗?
附加信息:在我见过的 msdn 示例中,它们不会 Dispose 或 Close。
编辑
感谢 Rick Sladkeys 的回答,我找到了解决方案: 我将 StreamResourceInfo.Stream 分配给 BitmapImage 的 StreamSource 属性。在 msdn 中写道:
如果您希望在创建 BitmapImage 后关闭流,请将 CacheOption 属性设置为 BitmapCacheOption.OnLoad。默认的 OnDemand 缓存选项保留对流的访问,直到需要位图为止,并且清理工作由垃圾收集器处理。
这意味着,BitmapImage
取得流的所有权。这就是为什么如果我手动关闭/处置流,内存分析器会显示错误:位图将保留对流的引用(BitmapCacheOption OnDemand),因此只要 BitmapImage 有效,GC 就不会释放它,但流已经明确处置。在这个具体示例中,处置是一个坏主意。
为了完整起见,我还在 msdn 中查找了调用 TextRange.Load
的上述链接的示例。对于 Load
来说,情况正好相反,Load
不获取所有权,因此流必须在完成后关闭/处置。
I use StreamResourceInfo.Stream
to get BitmapImage
s from resources. Is it correct to Close
and Dispose
the stream after using it?
I ask because in memory profiler, I get an error if I do so. Memory profiler says that a disposed instance has not been GCed.
If I look on the web, I only can find this post to this topic. In this post, the responding person says, that it is meaninfull to dispose. However if I look at the circumstances and on the effect, I don't think that this is right. Does someone know what is the right action?
Additional information: In the msdn examples I have seen, they don't Dispose or Close.
Edit
Thanks to Rick Sladkeys answer, I found the solution:
I assign StreamResourceInfo.Stream
to the StreamSource
-property of the BitmapImage
. In msdn is written:
Set the CacheOption property to BitmapCacheOption.OnLoad if you wish to close the stream after the BitmapImage is created. The default OnDemand cache option retains access to the stream until the bitmap is needed, and cleanup is handled by the garbage collector.
This means, BitmapImage
takes the ownership of the stream. And that's why memory profiler shows an error if I Close/Dispose the stream manually: Bitmap will hold a reference to the stream (BitmapCacheOption OnDemand) and therefore GC will not release it as long as the BitmapImage is valid, but the stream is already explicitely disposed. In this specific example, disposing is a bad idead.
For completness, I have also looked in msdn for the example of the above link where TextRange.Load
was called. For Load
, it is the opposite, Load
does not take the ownership and therefore the stream must be closed/disposed after finishing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这种混乱(我同意确实令人困惑)来自于流的所有权这一微妙但关键的概念。在 MSDN 示例中,您可以将它们视为“看,没有
Dispose
,没有Close
,所以我不应该这样做?”但简单的答案是某人必须负责关闭流。您可能正在调用的 API:
Application.GetResourceStream
返回一个
StreamResourceInfo
,它是流和 URL 的原始容器。显然StreamResourceInfo
不拥有该流。因此,当您调用Application.GetResourceStream
时,您现在拥有该StreamResourceInfo
中包含的流,并且如果您没有对它执行任何其他操作,您将负责关闭它。Application
API 通过将流的所有权作为值返回给我们,将流的所有权从自身转移给我们。现在,当您将流传递到另一个实体时,令人困惑的部分就出现了。让我们看一个 MSDN 示例:
在这个示例中,没有
Dispose
也没有Close
。但是,流的所有权转移从我们(调用者)到XamlReader
实例。溪流不再是我们的责任;我们已将所有权转让给其他人。事实上,XamlReader
在处理完流后确实会调用Close
。一个谜团解开了。这个问题之所以如此严重,是因为所有权的概念通常隐含在文档中,而我们应该“弄清楚它”。希望只是重新审视所有权的概念以及它是可转让的这一事实,将使您更容易感到不调用
Close
与安全性新主人将会。即使他们不这样做,这也不再是我们的问题了!The confusion, and I agree it is confusing, comes from the subtle but critical concept of ownership of the stream. In the MSDN examples you can look at them as say "Look, no
Dispose
, noClose
, so I'm not supposed to do that?"But the simple answer is that somebody has to be responsible for closing the stream. The API you are probably calling:
Application.GetResourceStream
returns a
StreamResourceInfo
that is a primitive container for a stream and an URL. Clearly theStreamResourceInfo
does not own the stream. So when you callApplication.GetResourceStream
you now own the stream that is contained in thatStreamResourceInfo
and, if you did nothing else with it, you would be responsible for closing it. TheApplication
API transfered ownership of the stream from itself to us by returning it as a value to us.Now the confusing part comes in when you pass the stream to another entity. Let's take an MSDN example:
Now in this example there is no
Dispose
and noClose
. But there is a transfer of ownership of the stream from us (the caller) to theXamlReader
instance. The stream is no longer our responsibility; we have passed ownership over to someone else. In fact,XamlReader
does callClose
when it is done with the stream. One mystery solved.The reason this is so problematic is that the concept of ownership is usually implicit in the documentation and we are supposed to "just figure it out." Hopefully just revisiting th concept of ownership and the fact that it is transferable will make it easier to feel comfortable not calling
Close
with the security that the new owner will. And even if they don't, it's not our problem anymore!