Я думаю объем переменной, в которой Вы "передаете", определит объем блокировки. т.е. переменная экземпляра будет в отношении экземпляра класса, тогда как статическая переменная будет для целого AppDomain.
Рассмотрение реализации наборов (использующий Отражатель), шаблон, кажется, следует за этим, переменная экземпляра под названием SyncRoot объявляется и используется для всех операций блокировки в отношении экземпляра набора.
1 миллион в день - это не много; Я бы просто использовал Activator.CreateInstance
(быстрый тест с использованием Activator.CreatInstance (Type)
показывает, что на моем скромном ноутбуке он может создавать 1M объектов из типа Type
] в ~ 2 с).
Мысли о быстром создании объектов:
: new ()
ограничение (нулевое усилие) DynamicMethod
и напишите IL (не сложно) Здесь показана реализация подхода new
(без внешнего ограничения : new ()
): ObjectFactory.cs
.
Для примера IL см. dapper-dot-net и il.Emit (OpCodes.Newobj, ...)
Я не думаю, что миллион в день - это слишком много для простого размышления. Я считаю, что вы чрезмерно оптимизируете, но в любом случае, как вы сказали, просто создайте фабричный класс с помощью одного вызова Activator.CreateInstance
и кешируйте его. Фактические экземпляры будут созданы с использованием вызова метода CreateInstance ()
для возвращаемого объекта.
public interface IClassFactory {
IClass CreateInstance();
}
public interface IClass {
// your actual class interface.
}
public class DefaultClassFactory : IClassFactory {
public IClass CreateInstance() {
return new DefaultClass(); // the implementation class
}
}
Где-то у вас будет поле static
типа IClassFactory
, которое вы установите один раз с помощью экземпляра DefaultClassFactory
или любых других классов, указанных в конфигурационном файле или в другом месте.
Некоторые мысли:
. Кэшируйте экземпляр для клонирования или Type в Dictionary
или Dictionary
.
ОТЛИЧНО! Подход фабрики классов, кажется, здесь лучший вариант.
Использование комбинации Assembly.CreateInstance (typeNameString)
в первом запросе, затем кэширование Type
в фабрике.
При последующих вызовах используйте Activator.CreateInstance (type)
.
При таком подходе он на 20% медленнее, чем при использовании собственного оператора New. Ничего страшного!
Статистика для создания 10 миллионов объектов Employee
выглядит следующим образом:
8 секунд с использованием оператора new
10 секунд с использованием Factory / Type Подход / Cache.
Вот пример кода, если кому-то интересно:
private IEmployee CachedClassFactory()
{
if(_typeCache == null)
{
// This is a one time hit to load the type into the cache
string typeName = "ClassFactoryTest.Employee";
string assemblyName = "ClassFactoryTest";
Assembly assembly = Assembly.Load(assemblyName);
IEmployee employee = assembly.CreateInstance(typeName) as IEmployee;
_typeCache = employee.GetType();
}
IEmployee instance = Activator.CreateInstance(_typeCache) as IEmployee;
instance.FirstName = "Raiford";
instance.LastName = "Brookshire";
instance.Birthdate = DateTime.Now.AddYears(-35);
instance.Age = 35;
return instance;
}
Как это обычно бывает, Джон Скит здесь твой друг. См. Его сообщение в блоге Создание отражения и исследование делегатов
Определите и реализуйте интерфейс вместо использования отражения.