Старый вопрос, но для всех, кто сталкивается с этим вопросом, как я:
Я считаю, что проблема в том, что 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.