Frage

Ich verwende eine System.Timers.Timer in meiner Asp.Net Anwendung und ich brauche die HttpServerUtility.MapPath Methode zu verwenden, die nur über HttpContext.Current.Server.MapPath verfügbar zu sein scheint. Das Problem ist, dass HttpContext.Current ist null wenn die Timer.Elapsed Ereignis ausgelöst wird.

Gibt es eine andere Art und Weise einen Verweis auf ein HttpServerUtility Objekt zu bekommen? Ich konnte es in meiner Klasse Konstruktor injiziert. Ist es sicher ? Wie kann ich sicher sein, es wird nicht Müll am Ende des aktuellen Auftrags Collected sein?

Danke!

War es hilfreich?

Lösung

Es ist möglich, HostingEnvironment.MapPath() statt HttpContext.Current.Server.MapPath() zu verwenden

Ich habe es noch nicht in einem Thread oder Timer-Ereignisse, obwohl versucht.


Einige (nicht lebensfähig) Lösungen, die ich in Betracht gezogen;

  • Die einzige Methode, die ich etwa auf HttpServerUtility Pflege ist MapPath. So als Alternative könnte ich AppDomain.CurrentDomain.BaseDirectory verwenden und meine Pfade daraus bauen. Das wird aber scheitern, wenn Ihre Anwendung virtuelle Verzeichnisse (Bergwerk der Fall ist).

  • verwendet
  • Ein weiterer Ansatz: Fügen Sie alle Pfade ich auf die die Global Klasse benötigen. Lösen Sie diese Pfade in Application_Start.

Andere Tipps

Ich weiß nicht, ob dies Ihr virtuellen Verzeichnisse Problem lösen, aber ich benutze diese für 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 ist nicht die perfekte Lösung, weil es eine sehr schwierige Klasse ist a href zu verspotten (siehe <= "https://stackoverflow.com/questions/8740498/how-to-unit-test-code-that-uses -hostingenvironment-MapPath "> Wie Unit-Test-Code, die HostingEnvironment.MapPath verwendet).

Für diejenigen, die Testbarkeit benötigen, ein besserer Weg könnte sein, Ihre eigene Weg-Mapper-Schnittstelle zu erstellen, wie vorgeschlagen von https: // Stackoverflow .com / a / 1231962/85196 , mit Ausnahme implementieren es als

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

Das Ergebnis ist leicht mockable nutzt Hostingenvironment intern, und könnte sogar möglicherweise Adresse ase69s Sorge zugleich.

Können Sie nicht die MapPath Funktion aufrufen, bevor Sie den Timer starten und einfach das Ergebnis zwischenspeichern? Ist es unbedingt erforderlich, den MapPath Anruf innerhalb des Tick-Ereignisses hat?

Wenn die Timer verstreichen, gibt es keinen aktuellen HTTP-Kontext ist. Dies liegt daran, die Timer-Ereignisse nicht auf eine bestimmte HTTP-Anfrage in Zusammenhang stehen.

Was Sie tun sollten, ist HttpServerUtility.MapPath verwenden, wo HTTP Kontext zur Verfügung steht. Sie können es in einen der Anforderungspipeline Ereignisse (wie Page_Load) oder in einem Global.asax Ereignisse wie Application_Start.

Weisen Sie das MapPath Ergebnis einer Variablen zugänglich von der Timer.Elapsed Ereignis, wo Sie Path.Combine nutzen, um die Position einer bestimmten Datei, die Sie benötigen.

ich glaube, den Grund dafür, warum es zu diesem Zeitpunkt null ist (wenn man darüber nachdenkt), ist, dass der Timer abgelaufen Ereignis nicht als Teil einer HTTP-Anforderung auftritt (daher kein Zusammenhang). Es zeichnet sich durch etwas auf dem Server verursacht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top