HttpModule распространяется среди рабочих потоков? - PullRequest
6 голосов
/ 12 апреля 2010

Нужно ли блокировать доступ к членам экземпляра?

Пример:

public class HttpModule : IHttpModule
{
    //...

    Dictionary<int, int> foo;

    void UseFoo(int a, int b)
    {
        foo[a] = b;
    }
}

Ответы [ 4 ]

4 голосов
/ 12 апреля 2010

Это не совсем ясно для меня до сих пор из документации MSDN, но я нашел сообщение на форуме от того, кто утверждает, что знает ответ . Похоже, вы не должны ожидать, что плохие вещи произойдут с вашей реализацией, но вы должны знать, что состояние foo не обязательно будет общим для всех результатов, поскольку ваш HttpModule будет создан один раз за HttpApplication, который IIS решает оставить в своем пуле.

1 голос
/ 09 августа 2012

Я хотел бы предложить здесь свои выводы, связанные с этим вопросом, как я наблюдал в IIS6:

Я много занимался этой проблемой в IIS6 и нашел несколько интересных результатов, использующих log4net и рефлексию для захвата истории выполнения. Я обнаружил, что за кулисами происходит обширное «управление потоками». Кажется, что существует «первичная» серия потоков, которая соответствует от 1: 1 до HttpApplication. Однако эти потоки не должны обрабатывать конвейер исключительно по вашему запросу. Различные различные подпотоки могут быть вызваны при обращении к этим экземплярам. Последующие новые запросы и запросы ресурсов, используемые вашим приложением, по-видимому, содержат некоторую постоянную информацию, относящуюся к вашему первоначальному запросу, но еще никогда полностью не обрабатываются исходным потоком, указывающим некоторый тип отношений. Я не мог различить какой-либо конкретный образец (кроме того, что я ранее описал) относительно того, какие элементы были разделены на другие потоки, поскольку это было на первый взгляд случайным. Мой вывод к этому доказательству состоит в том, что существует какая-то концепция иерархического объединения? происходит, когда некоторое неизвестное подмножество ссылочных элементов наследуется в дочерних потоках через родительскую ссылку.

Так что в качестве ответа я бы сказал, что HttpModules разделены между потоками. С точки зрения блокировки значений экземпляров это будет применимо, если значения применяются ко всем запросам, которые используют модуль и должны поддерживать некоторое состояние. Я мог бы счесть это полезным, если пытался поддерживать значения экземпляров с состоянием, которые дорого выяснить, чтобы их можно было повторно использовать в последующих запросах.

Эта проблема беспокоила меня в течение некоторого времени, надеюсь, эта информация кому-то поможет.

1 голос
/ 13 декабря 2011

Статья, опубликованная Джимом, интересна, но, как говорит Джим, в ней ничего не говорится о безопасности потоков.

Полагаю, вам понадобится механизм блокировки только в том случае, если вы инициализируете статические элементы или выполняете инициализацию «только один раз», то есть инициализируете статический ресурс.

Я не мог сделать вывод из MSDN или статьи, упомянутой Джимом, что нам нужен механизм блокировки при инициализации нестатических переменных класса.

1 голос
/ 12 апреля 2010

Я недавно нашел статью, которая слегка затрагивает этот вопрос: http://www.dominicpettifer.co.uk/Blog/41/ihttpmodule-gotchas---the-init---method-can-get-called-multiple-times

Он не упоминает потоки, а только говорит, что рабочий процесс будет

создать как можно больше HttpApplication объекты, как он думает, что нужно, то это объединит их для производительности причины, повторное использование экземпляров как новых запросы приходят перед отправкой обратно в бассейн.

Следуя коду из ссылки, вы можете быть уверены, что ваш код инициализации выполняется один раз в поточно-ориентированном виде:

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; 
            } 
        } 
    } 
}

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

...