Как получить доступ к HttpServerUtility.Метод MapPath в потоке или таймере?

StackOverflow https://stackoverflow.com/questions/111927

Вопрос

Я использую System.Timers.Timer в моем приложении Asp.Net и мне нужно использовать HttpServerUtility.MapPath метод, который, кажется, доступен только через HttpContext.Current.Server.MapPath.Проблема в том, что HttpContext.Current является null когда Timer.Elapsed срабатывает событие.

Есть ли другой способ получить ссылку на объект HttpServerUtility?Я мог бы внедрить это в конструктор моего класса.Безопасно ли это ?Как я могу быть уверен, что в конце текущего запроса не будет собран мусор?

Спасибо!

Это было полезно?

Решение

Это можно использовать HostingEnvironment.MapPath() вместо того, чтобы HttpContext.Current.Server.MapPath()

Однако я еще не пробовал это в потоке или событии таймера.


Некоторые (нежизнеспособные) решения, которые я рассматривал;

  • Единственный метод, который меня волнует на HttpServerUtility является MapPath.Так что в качестве альтернативы я мог бы использовать AppDomain.CurrentDomain.BaseDirectory и строю свои пути исходя из этого. Но это приведет к сбою, если ваше приложение использует виртуальные каталоги (У меня так и есть).

  • Другой подход:Добавьте все пути, которые мне нужны, к Global класс.Разрешите эти пути в Application_Start.

Другие советы

Я не знаю, решит ли это проблему с вашими виртуальными каталогами, но я использую это для MapPath:

public static string MapPath(string path)
{
    if (HttpContext.Current != null)
        return HttpContext.Current.Server.MapPath(path);

    return HttpRuntime.AppDomainAppPath + path.Replace("~", string.Empty).Replace('/', '\\');
}

HostingEnvironment не является идеальным решением, потому что это очень сложный класс для моделирования (см. Как выполнить модульное тестирование кода, использующего среду HostingEnvironment.MapPath).

Для тех, кому нужна возможность тестирования, лучшим способом может быть создание собственного интерфейса path-mapper, как предложено https://stackoverflow.com/a/1231962/85196, за исключением реализации его как

public class ServerPathMapper : IPathMapper { 
 public string MapPath(string relativePath) { 
      return HostingEnvironment.MapPath(relativePath); 
 } 
} 

Результат легко поддается макетированию, использует HostingEnvironment внутренне и даже потенциально может адресовать беспокойство ase69s в одно и то же время.

Можете ли вы не вызывать функцию MapPath перед запуском таймера, а просто кэшировать результат?Абсолютно ли необходимо иметь вызов MapPath внутри события tick?

По истечении таймера текущий HTTP-контекст отсутствует.Это связано с тем, что события таймера не связаны с конкретным HTTP-запросом.

Что вам следует сделать, так это использовать HttpServerUtility.MapPath, где доступен контекст HTTP.Вы можете сделать это в одном из событий конвейера запросов (например, Page_Load) или в глобальном событии.asax, таком как Application_Start .

Присвоите результат MapPath переменной, доступной из таймера.Прошедшее событие, где вы могли бы использовать Path .Объедините, чтобы получить местоположение определенного файла, который вам нужен.

Я думаю, причина, по которой в данный момент оно равно null (если вы подумаете об этом), заключается в том, что событие истечения таймера не происходит как часть HTTP-запроса (следовательно, нет контекста).Это вызвано чем-то на вашем сервере.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top