Как уже упоминали другие, шаблон Dispose является способом решения этой проблемы. Если объект ClassTwo живет в течение короткого времени, вы можете использовать оператор C # using, чтобы гарантировать, что Dispose вызывается после того, как вы закончили использовать объект:
using (var foo = new ClassTwo())
{
foo.Bar();
}
Чтобы найти причину таких проблем, вам нужно использовать профилировщик памяти. dotTrace уже упоминался, и еще одним хорошим примером является SciTech Memory Profiler . Что вам нужно найти, так это корневой путь к объекту, который, по вашему мнению, следует собирать, но это не так. Корневые пути - это причина, по которой объект не собирается - потому что через транзитивные ссылки объект, который гарантированно будет живым (корень GC), ссылается на ваш объект, который вы хотите убить.
Эти профилировщики памяти очень полезны для определения того, какие корни GC вызывают у вас проблемы, и каковы пути ссылки от корня к вашему объекту. Где-то вдоль этого корневого пути будет ссылка, которая неуместна и является причиной проблемы.
В вашем коде причиной того, что объект ClassTwo не был собран, может быть либо тот факт, что MainWindow имеет статическую ссылку на объект ClassOne, либо то, что обработчик события от ClassOne до ClassTwo не был отцеплен. Статические ссылки являются одним примером GC Roots - поэтому все ссылки classOne будут живы, пока эта статическая ссылка в MainWindow не будет изменена.
Является ли проблема статическим или обработчиком событий, зависит от сценария вашего приложения - должен ли объект ClassOne также быть собран - неправильно ли иметь статическую ссылку на него? Или желаемое поведение статической ссылки - это classOne долгоживущий объект, а classTwo недолговечный, и в этом случае classTwo должен быть Disposed по окончании его жизни, а Dispose должен отцепить обработчик события.
Это хорошая статья для изучения .Net GC, написанная Джеффри Рихтером: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx. Сейчас она немного устарела, в последние годы появились новые дополнения к GC, но это отличное место для начала.