2013-04-15 1 views
1

От MSDN:явно собирает DynamicMethod

Вы можете использовать класс DynamicMethod для создания и выполнения метода во время выполнения, без создания динамической сборки и динамического типа содержать метод. Исполняемый код, созданный компилятором «точно в срок» (JIT), восстанавливается при восстановлении объекта DynamicMethod . Динамические методы - наиболее эффективный способ генерации и выполнения небольших количеств кода.

У меня есть следующий код:

Type returnType = typeof(string); 
Type[] argTypes = { typeof(string), typeof(IEnumerable<string>) }; 

var dynamicMethod = new DynamicMethod("DynamicMethod1", returnType, argTypes); 
ILGenerator ilGen = dynamicMethod.GetILGenerator(); 
const string Returned = "returned"; 
ilGen.Emit(OpCodes.Ldstr, Returned); 
ilGen.Emit(OpCodes.Ret); 

var handler = 
    (Func<string, IEnumerable<string>, string>) 
    dynamicMethod.CreateDelegate(typeof(Func<string, IEnumerable<string>, string>)); 

т.е. я создать динамический метод с некоторым простым телом, то я хочу, чтобы сохранить делегат статического свойства. После нескольких вызовов этого делегата я хочу восстановить/собрать метод и воссоздать его другим телом (я написал интерпретируемый язык, который интерпретирует мой собственный синтаксис для байт-кода MSIL - что-то вроде компилятора) и сохраняет новый делегат в статическом свойстве.

Как я могу явно собирать/восстанавливать динамический метод?

+3

точно так же, как любой объект в C#. Не ссылайтесь на нее и не позволяйте ее собирать. –

+0

Если я просто удалю все мои ссылки на динамический метод, я не знаю момента, когда GC удалит этот метод из памяти, и я не знаю, когда я могу создать новый метод с тем же именем («DynamicMethod1»). –

+2

Но, конечно, имя, которое вы передаете, совершенно не имеет значения для целей обзора. Если это не так, что произойдет, если какой-нибудь другой API попытается создать метод с тем же именем? Просто удалите все ссылки, пусть это будет собрано в будущем, и создайте замену, когда захотите. Важно то, что дескриптор экземпляра 'DynamicMethod', а не его (произвольное) имя. –

ответ

0

Вы не можете использовать DynamicMethod явно, потому что он не реализует интерфейс IDisposable. Однако вы можете сказать GarbageCollector, когда вы хотите, чтобы собрать: System.GC.Collect();

Это «Принудительно немедленного сбора мусора всех поколений» в соответствии с MSDN

+0

Обратите внимание, что не рекомендуется явно вызывать 'GC.Collect()' – TiMoch

+0

Это путь, если вы хотите принудительно собрать коллекцию, не так ли? – Mzn

+0

Да, это так. Однако полная коллекция остановит все потоки выполнения. Эмпирическое правило состоит в том, чтобы доверять GC для сбора, когда это необходимо. Динамические методы обычно легки и давление памяти, которое они налагают, настолько низкое, что их сбор не должен вызывать беспокойства. Это немного похоже на настоящую сборку мусора, вы не просите об общей коллекции мусора, потому что вы просто оставили один мешок в передней части своего дома. Что вы делаете, так это ждать, пока регулярная сборка мусора не произойдет еженедельно. – TiMoch