VB.NET 'someObj' расположен не по всем путям исключений - я не хочу его утилизировать. Мой подход неверен? - PullRequest
1 голос
/ 11 марта 2011

VB.NET 2010, .NET 4

Здравствуйте,

Я попробовал запустить анализ кода в первый раз и обнаружил, что многие другие пользователи SO, делающие то же самое, обнаружили: изобилиеиз

В методе SomeMethod () объект SomeObject расположен не по всем путям исключений.Вызовите System.IDisposable.Dispose для объекта SomeObject до того, как все ссылки на него выйдут из области видимости.

предупреждений ( CA2000 ).Я читал об этой теме в SO здесь несколько других тем, большинство из которых было связано с рассматриваемым объектом, возможно, вызывая исключение за пределами блока try и т. Д.

Но как насчет этого?

Private SomeContainer As New Panel
Private Sub SomePopulatorMethod()
  '..stuff..'
  For i As Integer = 0 To 9
    Dim newLabel as New Label
    newLabel.Text = i.ToString
    SomeContainer.Controls.Add(newLabel)
  Next
  '..other stuff..'
End Sub

В этом случае я не хочу выбрасывать newLabel, поскольку он должен оставаться на панели.Я делаю такие вещи, когда динамически настраиваю вспомогательную форму, где я создаю группу пар текстовое поле / метка для представления некоторого набора данных.Является ли этот подход в корне неверным?Если так, как еще я должен пойти об этом?Я на самом деле (вроде) в порядке, просто позволяя лгать спящим собакам, но предупреждения заставляют меня грустить ... Я хотел бы сделать все правильно, если бы только я мог знать, как.

Любое понимание будет оценено!
Заранее спасибо,
Брайан

Ответы [ 2 ]

1 голос
/ 26 июня 2013

Старый вопрос, но для всех, кто сталкивается с этим вопросом, как я:

Я считаю, что проблема в том, что Label будет выделять неуправляемую память. Когда .NET освобождает его, неуправляемая память освобождается , а не . Если вы передадите его SomeContainer, то SomeContainer, когда это будет сделано, вызовет Dispose, что освободит неуправляемую память. Так что все в порядке, если вы дойдете до вызова SomeContainer.Control.Add. Но если что-то пойдет не так с newLabel.Text = i.ToString , неуправляемая память исчезнет, ​​пока ваша программа не остановится.

Что .NET хочет, чтобы вы сделали в этом случае, - это установите блок try вокруг назначения и вызовите Dispose, если с ним что-то не так. Теперь у вас не может быть утечки памяти независимо от того, насколько сумасшедшими становятся ваши данные. (Мне трудно понять, что может пойти не так с этой строкой, но я не думаю, что вы получили бы ошибку, если бы она работала каждый раз.) Я не думаю, что программистам следует беспокоиться об этом но если вы используете .NET и не можете допустить утечку памяти (как, например, в случае серверной программы, которая много месяцев работает очень интенсивно), то, вероятно, неплохо сделать все правильно.

Обновление после проведения дополнительных исследований:

Забудьте блоки try / catch. Сделайте это (поменяв местами последние две строки):

Dim newLabel as New Label
SomeContainer.Controls.Add(newLabel)
newLabel.Text = i.ToString

Теперь, когда бомбы i.ToString это не ваша проблема. У SomeContainer уже есть newLabel, и он отвечает за вызов Dispose.

1 голос
/ 11 марта 2011

Вы уверены, что вас не волнует проблема, упомянутая в последнем абзаце статьи MSDN, на которую вы ссылались?

Я не могу сказать, что ваш подход неверен, а наоборот.Вообще говоря, вам даже не нужно беспокоиться о том, является ли объект одноразовым, если только он не предписывает, что его нужно использовать очень специфическим образом (как в случае с блоком using(x) { ... } в C #).Например, поток реализует IDisposable и может использоваться таким образом, или вы можете просто вызвать Close (), что в конечном итоге и делает, когда он удаляется.

Большинство элементов управления Forms являются компонентами, которые по определению реализуют IDisposable.было бы довольно утомительно, если бы вам приходилось отслеживать их все с помощью блоков try / catch.Если это предупреждение появляется из-за того, что компилятор VB вставляет проверки арифметического переполнения во все элементы, просто отключите проверки или проигнорируйте предупреждение.

...