Как правильно создать поток для ввода-вывода базы данных в веб-сервисе asmx? - PullRequest
1 голос
/ 30 ноября 2009

У меня есть короткий защищенный раздел блокировки в методе (который полностью обслуживает запрос), который выполняет все инициализации (и т. Д., Связанные с журналом). Таким образом, только 1 поток может быть там одновременно. В этом разделе я также загружаю системные данные из базы данных, если они не загружены. Естественно, это выполняется только по первому запросу, и не имеет значения, что это занимает время, и никакие потоки не могут распространяться, поскольку это делается только один раз (по фиктивному запросу).

    static public void LoadAllSystemData()
    {
        SystemData newData = new SystemData(); //own type (etc. Hashtables in Hashtables).
        LoadTables(ref newData);
        LoadClasses(ref newData);
        LoadAllSysDescrs(ref newData);
        LoadFatFields(ref newData);
        LoadAllFields(ref newData);
        _allData = newData;
    }

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

    static public Hashtable GetTables()
    {
        return _allData.Tables;
    }

Теперь в разделе, защищенном блокировкой, должен быть метод, который проверяет, старше ли системные данные, чем 24 часа, и обновляет их. Если это было сделано просто путем вызова метода (из секции, защищенной блокировкой) ниже, этот поток занимает много времени, и никакой другой поток не может войти в секцию, защищенную блокировкой.

   static public void CheckStatus()
   {
       DateTime timeStamp = DateTime.Now;
       TimeSpan span = timeStamp.Subtract(_cacheTimeStamp);
       if (span.Hours >= 24)
       {
           LoadAllSystemData();
           _cacheTimeStamp = DateTime.Now;
       }
    }

Мои вопросы:

  1. Как создать поток, не являющийся пулом потоков, лучшим способом обработки ввода-вывода, чтобы рабочий поток пулов потоков мог распространяться, и все потоки проводили минимальное время в защищенной секции блокировки?

  2. Является ли _allData = newData; в LoadAllSystemData атомарный? Если это так, то это лучший способ реализовать это, поэтому методы GetXxx, такие как GetTables, не нуждаются в блокировке!

  3. Есть ли способ получить LoadAllSystemData для вызова перед запросами? Например на iisreset?

Заранее спасибо за ваши ответы!

Ответы [ 2 ]

0 голосов
/ 30 ноября 2009

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

  • Как предварительно загрузить данные, необходимые для моей службы, до обработки любых законных запросов?
  • Как мне убедиться, что предварительно загруженные данные загружаются "один раз"?
  • Как обновить предварительно загруженные данные по расписанию, т.е. каждые 24 часа?

Понимание конвейера и структуры событий Asp.Net поможет вам понять ответы на эти вопросы.

Во-первых, конвейер Asp.Net предоставляет одноразовую область выполнения в Application_Start. Это срабатывает один раз за цикл приложения. Это также будет запускать в «iisreset», который циклически повторяет каждое приложение для данного сервера. Однако сами циклы приложений будут перезапускаться самостоятельно, в зависимости от их конфигурации. Все из которых управляются через настройки IIS.

Во-вторых, Asp.Net - это система запросов; он не будет запускать события обновления для вас, и вы не можете использовать его в качестве планировщика. Вам нужен внешний агент, который будет действовать для вас.

Вот что вы могли бы делать:

  1. Добавьте предварительно загруженную подпрограмму данных в Application_Start.
  2. Сконфигурируйте настройки цикла приложений вашего веб-сайта каждые 24 часа.

Это обеспечит загрузку ваших данных один раз через Application_Start. Это обеспечит загрузку ваших данных до того, как ваш сайт обработает какие-либо запросы. Наконец, это обеспечит обновление ваших данных каждые 24 часа.

Вот что я сделал бы сделать:

  1. Добавить предварительно загруженную подпрограмму данных в Application_Start.
  2. Измените предварительно загруженную подпрограмму для данных, чтобы использовать Asp.Net Cache вместо статического использования.
  3. Изменить данные поиска для извлечения данных из кэша и перезагрузить, если данные не найдены.
  4. Предоставить возможность системе диагностики / мониторинга, то есть nagios, асинхронно обновлять данные с помощью вызова веб-метода, то есть preload_refresh ().

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

Как всегда, ваш пробег может отличаться. Надеюсь, это поможет.

0 голосов
/ 30 ноября 2009

Чтобы ответить на часть вашего вопроса в любом случае, вы можете использовать метод «Application_Start» в Global.asax для выполнения оператора при запуске приложения, если вы хотите предварительно заполнить данные, как только приложение будет подключено .

...