2016-03-19 8 views
0

Один из моих последних проектов включал отправку напоминаний по электронной почте на основе некоторой напоминания. Отправка электронной почты выполняется в асинхронном задании с использованием 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.

ответ

0

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

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

static readonly string hostName = "your-host"; 
static readonly string virtualPath = "your-virtual-path"; 
public static String GetCurrentBasePath(String prefix = "http://") 
{ 
    return String.Format("{0}{1}{2}", 
     prefix,           // protocol 
     hostName,   // host 
     virtualPath // virtual application path 
    ); 
} 
+0

Я использую Quarz.net, но воспроизводимая с помощью новой темы, задач (TPL) или асинхронная/Await. По сути, он выполняет задания, выполняемые в IIS, вместо создания службы Windows или чего-то подобного. – Alexei

+0

Справа. Как я уже сказал, мне кажется, что если вы ЗНАЕТЕ, какие значения вы пытаетесь вычислить, я думаю, что вам лучше устанавливать их как внутренние значения readonly. Обеспечивает безопасность потоков и экономит ваши циклы. – pimbrouwers

 Смежные вопросы

  • Нет связанных вопросов^_^