ASP.NET + неуправляемый API с поддержкой потоков
Я думаю о приложении ASP.NET, которое использует ESENT для настойчивости.
На данный момент это просто мой хобби-проект, поэтому требования очень гибкие. Однако я бы хотел, чтобы он работал на Windows 7, Windows 2008 и 2008 R2, с.NET 3.5 и выше и настройками IIS по умолчанию.
В ESENT для большинства операций требуется открыть объект сеанса. В документации сказано: "Сеанс отслеживает, в каком потоке он использовался, и выдает ошибку, если используется в нескольких потоках с открытой транзакцией". В документации API упоминаются собственные потоки, а не управляемые потоки.
Я предполагаю, что операция открытого сеанса является относительно дорогой, поэтому я не хочу открывать / закрывать сеанс для каждого HTTP-запроса.
Вот мои вопросы, наконец.
Как в asp.net я инициализирую / деинициализирую что-то ровно один раз в каждом нативном потоке, который выполняет мой код C#?
Будет ли работать код, указанный ниже, для меня?
Есть ли что-то плохое, чего я не знаю, в том, чтобы поддерживать управляемый поток asp.net постоянно прикрепленным к собственному потоку методом BeginThreadAffinity? Не протекают ли мои сессии после того, как IIS находится под нагрузкой в течение месяца без единой перезагрузки?
Заранее спасибо!
class MySession: IDisposable
{
[ThreadStatic]
private static MySession s_session = null;
public static MySession instance
{
get
{
return s_session ?? ( s_session = new MySession() );
}
}
private MySession()
{
Thread.BeginThreadAffinity();
// Open a new session, store the handle in non-static data member.
}
void IDisposable.Dispose()
{
// Close the session.
Thread.EndThreadAffinity();
}
}
3 ответа
Один хороший подход - создать пул сессий, чтобы потоки захватывали сессию из пула, а затем возвращали сессию после завершения. Сеанс может использоваться разными потоками, но ESENT будет жаловаться, если вы переносите сеанс между потоками, когда транзакция активна (хотя это поведение можно отключить).
Несколько крупных серверных приложений, использующих ESENT, используют подход сессионного пула, и он хорошо работает для них.
Наше текущее исследование показывает, что создание нового сеанса в page_load и размещение его в page_unload легко дает 600 запросов / сек с помощью wcat для простого скрипта, который выполняет поиск по индексу, и выполняет два других поиска для каждой возвращаемой строки.
другими словами, при правильной настройке отсутствующих параметров пул сеансов может не потребоваться.
В приведенном выше примере с maxsessions установлено значение 256. Настройка минимального размера кэша также способствует повышению производительности. на четырехъядерном тестовом сервере с 8 ГБ оперативной памяти.
Это, вероятно, не будет работать в этой форме, если вы действительно намерены оставить сеанс открытым для запросов.
Финализатор будет работать в отдельном потоке, и закрытие сеанса вызовет ошибку.
Скорее всего JET_errSessionInUse -
session was in use on another thread, or the session was not set or reset properly
в JetEndSession() во время Dispose().
Если вам действительно нужно использовать ESENT, возможно, вы сможете запустить и управлять выделенным пулом потоков вручную и маршалировать вызовы к ним или из них.