Путаница, и я согласен, что она сбивает с толку, происходит от тонкой, но критической концепции владения потока. В примерах 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
. Но там - это a передача права собственности потока от нас (вызывающей стороны) на экземпляр XamlReader
. Поток больше не наша ответственность; мы передали право собственности кому-то другому. Фактически, XamlReader
вызывает Close
, когда это делается с потоком. Одна загадка раскрыта.
Причина, по которой это так проблематично, состоит в том, что концепция владения обычно подразумевается в документации, и мы должны "просто разобраться". Надеемся, что просто пересмотрев концепцию владения и тот факт, что она может быть передана, будет легче чувствовать себя не , звоня Close
с безопасностью, которую новый владелец сделает . И даже если они этого не сделают, это больше не наша проблема!