.net - tiempo - ¿Cómo acceder al método HttpServerUtility.MapPath en un Thread o Timer?
thread c# ejemplo (6)
Uso System.Timers.Timer
en mi aplicación Asp.Net y necesito usar el método HttpServerUtility.MapPath
que parece estar disponible solo a través de HttpContext.Current.Server.MapPath
. El problema es que HttpContext.Current
es null
cuando se Timer.Elapsed
evento Timer.Elapsed
.
¿Hay alguna otra manera de obtener una referencia a un objeto HttpServerUtility? Podría inyectarlo en el constructor de mi clase. Es seguro ? ¿Cómo puedo estar seguro de que no será un Recolector de Basura al final de la solicitud actual?
¡Gracias!
¿No puede llamar a la función MapPath antes de iniciar el temporizador, y simplemente almacenar en caché el resultado? ¿Es absolutamente necesario tener la llamada MapPath dentro del evento tick?
Creo que el motivo por el que es nulo en ese momento (si lo piensas) es que el evento del temporizador transcurrido no ocurre como parte de una solicitud HTTP (por lo tanto, no hay contexto). Es causado por algo en tu servidor.
Cuando el temporizador transcurre, no hay un contexto HTTP actual. Esto se debe a que los eventos del temporizador no están relacionados con una solicitud HTTP específica.
Lo que debe hacer es usar HttpServerUtility.MapPath, donde el contexto HTTP está disponible. Puede hacerlo en uno de los eventos de interconexión de solicitudes (como Page_Load) o en un evento Global.asax como Application_Start.
Asigne el resultado de MapPath a una variable accesible desde el evento Timer.Elapsed, donde puede usar Path.Combine para obtener la ubicación de un archivo específico que necesita.
Es posible usar HostingEnvironment.MapPath()
lugar de HttpContext.Current.Server.MapPath()
Sin embargo, todavía no lo he probado en un tema o evento de temporizador.
Algunas soluciones (no viables) que consideré;
El único método que me importa en
HttpServerUtility
esMapPath
. Entonces, como alternativa, podría usarAppDomain.CurrentDomain.BaseDirectory
y construir mis rutas a partir de esto. Pero esto no funcionará si su aplicación usa directorios virtuales (Mine lo hace).Otro enfoque: agregue todas las rutas que necesito a la clase
Global
. Resuelva estos caminos enApplication_Start
.
HostingEnvironment no es la solución perfecta, ya que es una clase muy difícil de burlar (consulte Cómo probar el código de unidad que usa HostingEnvironment.MapPath ).
Para aquellos que necesitan capacidad de prueba, una mejor manera podría ser crear su propia interfaz path-mapper según lo propuesto por https://.com/a/1231962/85196 , excepto implementarlo como
public class ServerPathMapper : IPathMapper {
public string MapPath(string relativePath) {
return HostingEnvironment.MapPath(relativePath);
}
}
El resultado es fácilmente burlable, utiliza HostingEnvironment internamente y podría incluso abordar la preocupación de ase69s al mismo tiempo.
No sé si esto resolverá su problema de directorios virtuales, pero yo uso esto para 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(''/'', ''//');
}