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