#c# #.net #asp.net #multithreading #entity-framework-4
#c# #.net #asp.net #многопоточность #entity-framework-4
Вопрос:
У меня есть класс Worker, который периодически отправляет электронные письма, я запускаю в Global.asax.cs в App_start()
public static class Worker
{
public static void Start()
{
ThreadPool.QueueUserWorkItem(o => Work());
}
public static void Work()
{
var r = new DbContext();
var m = new MailSender(new SmtpServerConfig());
while (true)
{
Thread.Sleep(600000);
try
{
var d = DateTime.Now.AddMinutes(-10);
var ns = r.Set<Notification>().Where(o => o.SendEmail amp;amp; !o.IsRead amp;amp; o.Date < d);
foreach (var n in ns)
{
m.SendEmailAsync("noreply@example.com", n.Email, NotifyMailTitle(n) " - forums", NotifyMailBody(n));
n.SendEmail = false;
}
r.SaveChanges();
}
catch (Exception ex)
{
ex.Raize();
}
}
}
}
Итак, я сохраняю этот dbcontext в течение всего срока службы приложения, это хорошая практика?
Ответ №1:
DbContext — очень легкий объект.
Не имеет значения, остается ли ваш DbContext живым или вы создаете его непосредственно перед выполнением вызова, потому что фактическое соединение с БД открывается только тогда, когда вы отправляете изменения или перечисляете запрос (в этом случае он закрывается в конце перечисления).
В вашем конкретном случае. Это не имеет никакого значения.
Прочитайте Linq DataContext и Dispose для получения подробной информации об этом.
Ответ №2:
Я бы обернул его в using
инструкцию внутри Work
и позволил пулу подключений к базе данных делать это:
using (DbContext r = new DbContext())
{
//working
}
ПРИМЕЧАНИЕ: я не уверен на 100%, как DbContext обрабатывает соединения с БД, я предполагаю, что он открывает один.
Не рекомендуется поддерживать «живое» соединение с базой данных в течение всего срока службы приложения. Вы должны использовать соединение, когда это необходимо, и закрыть его через API (using statement позаботится об этом за вас). Пул подключений к базе данных фактически открывает и закрывает соединения на основе требований к подключению.
Ответ №3:
Я согласен с @rick schott в том, что вы должны создавать экземпляр DbContext
, когда вам нужно его использовать, а не хранить его в течение всего срока службы приложения. Для получения дополнительной информации см. раздел Работа с объектами (Entity Framework 4.1), особенно раздел о времени жизни:
При работе с длительным контекстом учитывайте следующее:
По мере загрузки большего количества объектов и их ссылок в память потребление памяти контекстом может быстро увеличиваться. Это может вызвать проблемы с производительностью.
Если исключение приводит к тому, что контекст находится в невосстановимом состоянии, все приложение может завершиться.