Dispose of StreamResourceInfo.Stream

I am using StreamResourceInfo.Stream to get BitmapImage from resources. Is it correct to use the Close and Dispose stream after using it? I ask because in the memory profiler I get an error message if I do this. The memory profiler says the remote instance was not GCed.

If I look on the Internet, I can find this post in this thread. In this message, the defendant says that this means that he must dispose. However, if I look at the circumstances and the effect, I do not think this is correct. Does anyone know what the right action is?
Additional Information: In the msdn examples that I saw, they do not destroy or close.

Edit
Thanks to Rick Sladki's answer, I found a solution: I am assigning StreamResourceInfo.Stream to StreamSource -property BitmapImage . In msdn it is written:

Set the CacheOption property for BitmapCacheOption.OnLoad if you want to close the stream after creating BitmapImage. The OnDemand caching option by default retains access to the stream until the bitmap is needed, and the cleanup is handled by the garbage collector.

This means that BitmapImage takes control of the flow. And this is why the memory profiler shows an error if I manually close / delete the stream: Bitmap will contain a link to the stream (BitmapCacheOption OnDemand) and therefore the GC will not release it as long as BitmapImage is valid, but the stream is already explicitly located. In this particular example, deliverance is a bad ideal.
For completeness, I also looked at msdn using the example of the above link where TextRange.Load was called. For Load this is the opposite, Load does not accept ownership, and therefore the stream must be closed / deleted after completion.

+6
source share
1 answer

Confusion, and I agree that this is confusing, comes from a subtle but critical concept of stream ownership . In the MSDN examples, you can look at them as "Look, no Dispose , no Close , so shouldn't I?"

But the simple answer is that someone should be responsible for closing the stream. The API you are probably calling:

  • Application.GetResourceStream

returns StreamResourceInfo , which is a primitive container for the stream and URL. Obviously, StreamResourceInfo does not own the stream. Therefore, when you call Application.GetResourceStream , you now own the stream that is contained in this StreamResourceInfo , and if you have not done anything with it, you are responsible for closing it. The API Application transferred ownership of the flow from itself to us, returning it as a value to us.

Now the intricate part appears when you pass the stream to another object. Take the MSDN example:

 // 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; 

Now in this example there is no Dispose and no Close . But there is a transfer of ownership of the stream from us (the caller) to the XamlReader instance. Flow is no longer our responsibility; we moved on to someone else. In fact, XamlReader calls Close when it is done with the stream. One riddle is solved.

The reason this is so problematic is because the concept of ownership is usually implied in the documentation, and we should "just understand it." We hope that only a revision of the concept of ownership and the fact that it is portable will simplify the comfortable not calling Close with the security that the new owner will have . And even if they do not, this is no longer our problem!

+10
source

Source: https://habr.com/ru/post/889148/