Domanda

Uso un System.Timers.Timer nella mia applicazione Asp.Net e ho bisogno di usare il metodo HttpServerUtility.MapPath che sembra essere disponibile solo tramite HttpContext.Current.Server.MapPath . Il problema è che HttpContext.Current è null quando si attiva l'evento Timer.Elapsed .

Esiste un altro modo per ottenere un riferimento a un oggetto HttpServerUtility? Potrei iniettarlo nel costruttore della mia classe. È sicuro ? Come posso essere sicuro che non sarà Garbage Collected alla fine della richiesta corrente?

Grazie!

È stato utile?

Soluzione

È possibile utilizzare HostingEnvironment.MapPath () anziché HttpContext.Current.Server.MapPath()

Non l'ho ancora provato in un evento thread o timer.


Alcune soluzioni (non praticabili) che ho preso in considerazione;

  • L'unico metodo che mi interessa su HttpServerUtility è MapPath . Quindi, in alternativa, potrei usare AppDomain.CurrentDomain.BaseDirectory e costruire i miei percorsi da questo. Ma questo fallirà se la tua app utilizza directory virtuali (la mia lo fa).

  • Un altro approccio: Aggiungi tutti i percorsi di cui ho bisogno alla classe Global . Risolvi questi percorsi in Application_Start.

Altri suggerimenti

Non so se questo risolverà il tuo problema con le directory virtuali, ma lo uso per 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 non è la soluzione perfetta perché è una classe molto difficile da deridere (vedi Come unit test del codice che utilizza HostingEnvironment.MapPath ).

Per coloro che necessitano di testabilità, un modo migliore potrebbe essere quello di creare la propria interfaccia path-mapper come proposta da https: // stackoverflow .com / a / 1231962/85196 , tranne implementarlo come

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

Il risultato è facilmente deridibile, utilizza HostingEnvironment internamente e potrebbe persino indirizzare potenzialmente preoccupazione di ase69s allo stesso tempo.

Non puoi chiamare la funzione MapPath prima di avviare il timer e semplicemente memorizzare il risultato nella cache? È assolutamente necessario avere la chiamata MapPath all'interno dell'evento tick?

Allo scadere del timer, non esiste alcun contesto HTTP corrente. Questo perché gli eventi timer non sono correlati a una specifica richiesta HTTP.

Quello che dovresti fare è usare HttpServerUtility.MapPath dove è disponibile il contesto HTTP. Puoi farlo in uno degli eventi della pipeline della richiesta (come Page_Load) o in un evento Global.asax come Application_Start.

Assegna il risultato MapPath a una variabile accessibile dall'evento Timer.Elapsed, dove puoi usare Path.Combine per ottenere la posizione di un file specifico che ti serve.

Penso che il motivo per cui è nullo in quel momento (se ci pensate), è che l'evento trascorso dal timer non si verifica come parte di una richiesta HTTP (quindi non c'è contesto). È causato da qualcosa sul tuo server.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top