Проблема разрушения объекта с помощью MEF - PullRequest
1 голос
/ 06 декабря 2010

Я использую статическую переменную для хранения количества объектов.В конструкторе я увеличиваю эту переменную.Таким образом, я знаю, сколько экземпляров объекта создано.После использования объектов они разыменовываются.Я сомневаюсь, что MEF содержит ссылки на эти объекты, поэтому я заставляю GC выполнить очистку (используя метод GC.Collect()).Я ожидаю, что при следующем создании объекта эта переменная начнется с нуля, но она возобновится с последнего числа.Я добавил механизм ведения журнала в destructor для отслеживания, и объекты уничтожаются только после закрытия приложения.Могу ли я предположить, что MEF создал другие ссылки на эти объекты?

Я использую MEF и ExportFactory для создания своих объектов

Редактировать:

Возможно что-то сExportLifetimeContext должно быть сделано?

Ответы [ 4 ]

8 голосов
/ 06 декабря 2010

Я заставляю GC провести очистку

Если MEF все еще имеет ссылки на объекты, то, очевидно, это ничего не делает. Если объекты стали мусором, то сборщик мусора автоматически соберет их - если явно попросить сделать это, это всего лишь подсказка, которую можно игнорировать. В любом случае, это не обязательно.

Я поместил в деструктор механизм ведения журнала для отслеживания, и объекты уничтожаются только после закрытия приложения. Могу ли я предположить, что MEF создал другие ссылки на эти объекты?

MEF будет содержать ссылки на созданные объекты, чтобы он мог повторно возвращать одну и ту же ссылку, когда вы запрашиваете экспорт. Чтобы попросить MEF отказаться от этих ссылок, вы должны позвонить CompositionContainer.Dispose. Очевидно, что после этого вы больше не сможете повторно использовать контейнер, хотя можете создать новый.

MEF также является владельцем любых IDisposable объектов, которые он создает. Это означает, что когда вы утилизируете контейнер, он вызовет Dispose для любых таких объектов, прежде чем отказаться от ссылки.

Предпочтительно использовать вызовы Dispose для выполнения очистки, а не использовать финализаторы. Нет никакой гарантии, что финализаторы работают вообще .

редактирование:

Мне нужно уничтожить объект после его использования. Но я не хочу уничтожать контейнер. Я хочу, чтобы MEF был фабрикой для создания новых экземпляров запрашиваемой детали, и вызывающая сторона должна быть способна уничтожить объект, когда он больше не нужен. Вы можете помочь с этим?

Для этого ExportFactory . (Ранее он назывался PartCreator). К сожалению, он пока недоступен в .NET 4, если вы не используете Silverlight. Вы можете использовать предварительные версии codeplex , чтобы уже попробовать.

Если вы не хотите использовать предварительные выпуски MEF, вы можете реализовать что-то вроде ExportFactory самостоятельно, создав фабричные классы, которые обертывают контейнер, и используя GetExport и * 1041. * методы для приобретения и выпуска объектов. Не забудьте установить PartCreationPolicy, если вам нужно создать несколько экземпляров одной детали.

изменить 2: Я почему-то упустил, что вы уже все время используете ExportFactory. Вам просто нужно позвонить ExportLifeTimeContext.Dispose, когда вы закончите с объектом!

1 голос
/ 06 декабря 2010

Для общих объектов MEF будет хранить ссылки на них, пока контейнер жив.У вас могут быть запасные части, которые не были разделены, на ранних этапах при правильных обстоятельствах.Если вы используете ExportFactory, вам нужно избавиться от ExportLifetimeContext, возвращенного методом CreateExport, чтобы избавиться от любых нераздельных частей, созданных как часть запроса.Если вы вызвали метод GetExport для контейнера, вы можете вызвать метод ReleaseExport.Если вы получили экспорт каким-либо другим способом (например, SatisfyImports или чем-то еще), нет способа освободить его, поэтому вы можете реорганизовать свое приложение для использования ExportFactory или GetExport.

1 голос
/ 06 декабря 2010

Своевременное «уничтожение» (то есть завершение) объектов в CLR не является хорошей вещью, на которую можно положиться.Если вы делаете это в целях отладки, в этом нет необходимости.Вы можете узнать, сколько объектов какого-либо типа еще существует, следуя инструкциям в моем ответе на этот вопрос:

Утечки памяти в C # WPF

Если выдействительно стараемся сделать так, чтобы поведение вашего программного обеспечения зависело от количества экземпляров класса, которые не были восстановлены GC, тогда вам нужно переосмыслить свой дизайн.Будет несколько лучших способов добиться того, чего вы хотите.

0 голосов
/ 07 декабря 2010

MEF теперь имеет настольную версию, которая поддерживает ExportFactory. Хотя в названии есть слово «экспорт», вы должны реализовать его там, где вы выполняете «импорт». Вызов метода CreateExport() для создания нового экземпляра вашей детали вернет ExportLifetimeContext<T>, у этого объекта есть метод Dispose(), который можно будет использовать позже для освобождения экспортируемого объекта. Этот метод будет вызывать ваш объект Dispose() автоматически, и вам не нужно вызывать его вручную.

Это связано с тем, что контейнер сам является владельцем созданных объектов и даже со ссылкой на эти объекты, вызывающие их Dispose(), не влияет на них.

...