ASP.NET Threading: я должен использовать пул для действий с БД и электронной почтой? - PullRequest
1 голос
/ 02 декабря 2009

Я ищу лучший способ использования потоков с учетом масштабируемости и производительности.

На моем сайте у меня есть два сценария, которые требуют многопоточности:

  1. Триггер пользовательского интерфейса: например, пользователь нажимает кнопку, сервер должен прочитать данные из БД и отправить несколько электронных писем. Эти действия занимают время, и я не хочу, чтобы запрос пользователя задерживался. Этот сценарий случается очень часто.

  2. Фоновая служба: при запуске приложения оно запускает поток, который запускается каждые 10 минут, читает из БД и отправляет электронные письма.

Решения, которые я нашел:

A. Использовать пул потоков - BeginInvoke: Это то, что я использую сегодня для обоих сценариев. Он работает нормально, но использует те же потоки, которые обслуживают страницы, поэтому я думаю, что у меня могут возникнуть проблемы с масштабируемостью, это может стать проблемой?

B. Не использовать пул - ThreadStart: Я знаю, что запуск нового потока требует больше ресурсов, чем использование пула потоков. Может ли этот подход работать лучше для моих сценариев? Каков наилучший способ повторно использовать открытые темы?

C. Пользовательский пул потоков: Поскольку мои сценарии происходят часто, может быть, лучший способ - запустить новый пул потоков?

Спасибо.

Ответы [ 4 ]

4 голосов
/ 02 декабря 2009

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

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

0 голосов
/ 02 декабря 2009

Из трех ваших решений не используйте BeginInvoke. Как вы сказали, это отрицательно скажется на масштабируемости.

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

Однако имейте в виду, что веб-серверы иногда аварийно завершают работу, перезапускают AppPools и т. Д. Поэтому, если какая-либо работа в очереди должна быть надежно выполнена, то ее перенос из процесса, вероятно, является лучшей идеей (например, в Windows Обслуживание). Одним из способов сделать это, который сохраняет порядок запросов и поддерживает постоянство, является использование Service Broker. Вы записываете запрос в очередь компонента Service Broker со своего веб-уровня (с асинхронным запросом), а затем читаете эти сообщения из службы, работающей на том же компьютере или на другом. Вы также можете хорошо масштабировать таким образом, просто добавляя больше экземпляров сервиса (или больше потоков в нем).

Если это поможет, я подробно рассмотрю использование фонового потока и компонента Service Broker в своей книге, включая примеры кода: Сверхбыстрый ASP.NET .

0 голосов
/ 02 декабря 2009

Для первого сценария используйте ASP.NET Asynchronous Pages. Асинхронные страницы являются очень хорошим выбором, когда речь заходит о масштабируемости, поскольку во время асинхронного выполнения поток HTTP-запроса освобождается и может быть использован повторно.

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

0 голосов
/ 02 декабря 2009

Я делаю такие вещи, вызывая веб-сервис, который затем вызывает метод с использованием делегата асинхронно. Исходный вызов веб-службы возвращает Guid, чтобы разрешить отслеживание обработки.

...