Общий файл httpmodule среди рабочих потоков?
-
26-09-2019 - |
Вопрос
Должен ли я заблокировать доступ к членам экземпляра?
Пример:
public class HttpModule : IHttpModule
{
//...
Dictionary<int, int> foo;
void UseFoo(int a, int b)
{
foo[a] = b;
}
}
Решение
Это не кристально ясно, мне так далеко от документации MSDN, но я нашел Форум пост от тех, кто утверждает, что узнает ответ. Отказ Похоже, вы не должны ожидать плохие вещи случиться с вашей реализацией, но вы должны знать, что foo
состояние не обязательно будет передано по всем результатам, так как ваш HttpModule
будет создан один раз за HttpApplication
что IIS выбирает, чтобы держать в своем бассейне.
Другие советы
Я хотел предложить здесь мои выводы, связанные с этим вопросом, как я наблюдал в IIS6:
Я имел дело с этой проблемой широко в IIS6 и нашел несколько интересных результатов, использующих Log4net и отражение для захвата истории исполнения. То, что я обнаружил, что на сцене происходит обширная «управление нитью». Похоже, что есть «первичная» серия потоков, которые соответствует 1: 1 HttpApplication
. Отказ Эти темы, однако, не выполняют исключительно справиться с трубопроводом для вашего запроса. Различные разные подделки могу быть вызванным, когда эти экземпляры доступны. Последующие новые запросы и запросы на ресурсы, используемые вашим приложением, по-видимому, поделитесь какой-либо постоянной информацией, относящейся к вашему первоначальному запросу, но еще никогда не обрабатываются в исходном потоке, указывающей некоторые виды отношений. Я не мог заметить любой конкретный рисунок (кроме того, что я ранее описал), насколько элементы были отклонены на другие потоки, как это было, казалось бы, случайным. Мой вывод к этому доказательствам состоит в том, что есть некоторая концепция иерархического объединения? происходит там, где какое-то неизвестное подмножество ссылочных элементов унаследовано в дочерних потоках через родительскую ссылку.
Так как ответ, я бы сказал, что HttpModules
являются поделиться между потоками. С точки зрения значений экземпляра блокировки, это будет применимо, если значения применяются ко всем запросам, которые используют модуль и должны поддерживать некоторое состояние. Я мог видеть, что это полезно, если пытаться сохранить значения экземпляров состояния, которые дороги, чтобы выяснить, чтобы они могли быть использованы в последующих запросах.
Эта проблема некоторое время беспокоит меня, надеюсь, эта информация поможет кому-то.
Недавно я нашел статью, которая слегка касается этого вопроса:http://www.dominicpettifer.co.uk/blog/41/ihttpmodule-gotchas--te-init--method-can-get-called-multiple-times.
Это не упоминает нити, но только говорит, что рабочий процесс будет
Знамените как многие объекты httpapplication, как оно считает, что он нуждается в необходимости, то он будет пуливать их по причинам эффективности, повторное использование экземпляров, поскольку новые запросы приходят, прежде чем отправлять их обратно в пул.
Следуя коду из ссылки, вы можете быть уверены, что код INIT выполняется один раз в безопасном порядке:
private static bool HasAppStarted = false;
private readonly static object _syncObject = new object();
public void Init(HttpApplication context)
{
if (!HasAppStarted)
{
lock (_syncObject)
{
if (!HasAppStarted)
{
// Run application StartUp code here
HasAppStarted = true;
}
}
}
}
Я имел значение, чтобы настроить тестовое приложение для запуска этого и проверить его, просто чтобы увидеть, правда ли это, но у меня не было времени.
В статье, размещенной Джимом, интересна, но как Джим говорит, что не упоминается о безопасности потоков.
Я предполагаю, что вам нужен только механизм блокировки, если вы инициализируете статические элементы или выполняющие «только один раз» инициализации, т.е. инициализацию статического ресурса.
Я не мог сделать вывод из MSDN, ни статьи, упомянутой Джимом, что нам нужен механизм блокировки при инициализации нестатических переменных классов.