2015-01-30 7 views
0

Я читал везде, что «правильный» способ использовать контекст заключается в следующем:
Entity Framework 6 Контекст Lifetime

using (var Db = new MyDatabase()) 
{ 
    DoStuff(Db); 
} 

Но я нашел, что это будет болезненно медленным в некоторых случаях.
У меня есть функция, которая называется много, из разных потоков, через веб-запросы и ТОЛЬКО ЧИТАЕТ.

Это мой тестовый код:

var S = new Stopwatch() 
S.Start(); 
Parallel.For(
    0, 
    15000, 
    I => 
    { 
     var P = GetPostWebContent(I); 
    }); 

S.Stop(); 
Console.WriteLine(S.ElapsedMilliseconds); 


С 'рекомендуемых' методом время выполнения 303.6s за 15000 звонков, 20.24ms за звонок.


Теперь, сохраняя один контекст для каждого потока, я получаю очень разные результаты, используя следующий код:

[ThreadStatic] 
private static MyDatabase _Db; 
if (_Db == null) _Db = new DatabaseWebsite(); 
DoStuff(Db); 

И время выполнения 52.4s для 15000 звонков, 3.5ms на вызов.
Это означает, что это решение на 5,8 раз быстрее!

Я немного шокирован: я продолжаю читать в Интернете, что создание контекста не имеет большого значения и т. Д .; но в моем случае это имеет огромное влияние.
Я знаю, что с этой реализацией контекст будет расти по размеру, но я мог бы реализовать счетчик и повторно создавать контекст регулярно.
Есть ли что-нибудь, что помешало бы этому использовать? Как я сказал выше, вся операция READ ONLY, я ничего не пишу в базу данных.

+0

К сожалению, подавляющее большинство примеров имеют тенденцию замалчивать такие вещи, как управление памятью, прибегая к тому, «если мы запишем« использование », то GC будет просто починить позади нас». Это хорошо для примеров или простого кода, но вы быстро узнаете, что во многих случаях вам нужна более надежная стратегия, как только вы поймете основы вещей. – Claies

ответ

0

Это всего лишь рекомендация. Контекст не является потокобезопасным, поэтому наличие одного потока - хорошая идея, если производительность важна для вас.

Я склонен передавать контексты вокруг методов, которые работают в одном потоке, потому что я обнаружил проблемы с производительностью при создании контекстов. Он работал над производственным кодом для меня.

Смежные вопросы