Теория
Если объект A содержит ссылку на объект B, и вы присваиваете значение A null, то через некоторое время A будет удален сборщиком мусора. если есть еще другие, ссылающиеся на B, то B не является сборщиком мусора. Однако, если A был последним со ссылкой на B, то B также будет собран:
Person Joseph = new Person
{
Id = 1,
Address = new Address {Id = 10, ...},
...
};
Joseph.Address = new Address {Id = 11, ...}
Через некоторое время Адрес с Id 10 будет удален, потому что никто не имеет ссылки на него anymore.
Person Mary = new Person
{
Id = 2,
Address = Joseph.Address,
...
};
Joseph = null;
Через некоторое время Человек с Id 1 будет удален, потому что никто больше не имеет на него ссылки. Однако адрес с идентификатором 11 не будет собираться в мусор, потому что человек с идентификатором 2 содержит ссылку на него.
mary = null;
Теперь никто не имеет ссылки на адрес с идентификатором 11, поэтому он будет быть сборщиком мусора.
Обратно к вашему вопросу
- Вы создаете новый объект-контейнер
- Вы создаете новый объект NotifyIcon.
- Вы добавляете этот объект NotifyIcon к объекту компонентов
- Вы создаете новые объекты Timer, используя конструктор, который приказывает таймеру добавить себя в контейнер.
Таким образом, объект контейнера имеет ссылки на как созданные объекты NotifyIcon и Timer. Пока эти объекты не удалены из контейнера, и контейнер не удален и не собран мусором, этот контейнер будет содержать эти ссылки, и, следовательно, ни notifyIcon, ни таймер не будут собраны мусором.
components.Dispose();
Согласно справочному источнику System.ComponentModels.Container , это будет делать следующее:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
lock (syncObj) {
while (siteCount > 0)
{
ISite site = sites[--siteCount];
site.Component.Site = null;
site.Component.Dispose();
}
sites = null;
components = null;
}
}
Итак, Container.Dispose()
вызовет Dispose()
всех добавленных компонентов, а затем освободит ссылка на добавленные компоненты.
- Если у вас есть ссылки на эти компоненты в другом месте, то эти компоненты не будут собираться сборщиком мусора. Однако, поскольку они утилизированы, обычно их нельзя использовать.
- Если контейнер был единственным со ссылками, то после
Container.Dispose()
NotifyIcon и таймер могут быть собраны. - Поскольку у вас все еще есть ссылка на Контейнер, сам Контейнер не собирается. Поскольку он удален, Контейнер больше не может использоваться.
- Чтобы убедиться, что Контейнер собран, либо выведите ссылку go за пределы области видимости, либо присвойте ей значение null.
В каждом Form.Dispose()
вы найдете код, похожий на:
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
Когда форма удаляется, this.components также удаляется, что означает, что все IComponents, которые он содержит, удаляются, а ссылки удалены. Даже ссылка на Container.ComponentCollection удалена. Обратите внимание, что форма по-прежнему содержит ссылку на this.components, поэтому, хотя this.components больше не может использоваться.
Последнее немного странно: если вы больше не храните ссылки на свой NotifyIcon / Timer они собираются мусором, однако this.Components - нет, пока существует форма. Было бы лучше, если бы Form.Dispose также выпустил ссылку на this.components