Один из моих последних проектов включал отправку напоминаний по электронной почте на основе некоторой напоминания. Отправка электронной почты выполняется в асинхронном задании с использованием Quartz.net., и для этого требуется включить постоянную ссылку на объект в приложении.Почему текущий корневой виртуальный путь приложения ASP.NET MVC недоступен в другом потоке/задаче?
Однако, для того чтобы получить эту возможность, я должен быть в состоянии вычислить полный URL-адрес на основе идентификатора, хранящегося в очереди, используемой для задания. Ответ прост, так как HttpContext
недоступен в контексте темы.
Одним из решений является сохранение корневого пути приложения в очереди и использование его оттуда. Другой способ заключается в использовании функции, как следующее:
public static String GetCurrentBasePath(String prefix = "http://")
{
return String.Format("{0}{1}{2}",
prefix, // protocol
System.Net.Dns.GetHostEntry("").HostName, // host
System.Web.HttpRuntime.AppDomainAppVirtualPath // virtual application path
);
}
Однако, это имеет (серьезные) ограничения, так как должны быть предусмотрены протоколом, а также возвращает hostname
, не domain name
, что делает его бесполезным при наличии многократных Веб-приложения, привязанные к одному хосту.
Вопрос: есть ли базовый путь веб-приложения в другом потоке/задаче?. Я думаю, что другой контекст потока/задачи каким-то образом связан с ApplicationPool
, а не с WebApp
, и поскольку несколько WebApp
s могут использовать тот же ApplicationPool
, нет прямого соединения между контекстом потока и WebApp
.
Я использую Quarz.net, но воспроизводимая с помощью новой темы, задач (TPL) или асинхронная/Await. По сути, он выполняет задания, выполняемые в IIS, вместо создания службы Windows или чего-то подобного. – Alexei
Справа. Как я уже сказал, мне кажется, что если вы ЗНАЕТЕ, какие значения вы пытаетесь вычислить, я думаю, что вам лучше устанавливать их как внутренние значения readonly. Обеспечивает безопасность потоков и экономит ваши циклы. – pimbrouwers