Pergunta

Eu uso um System.Timers.Timer na minha aplicação Asp.Net e eu preciso usar o método HttpServerUtility.MapPath que parece ser apenas disponível através HttpContext.Current.Server.MapPath. O problema é que HttpContext.Current é null quando o evento é acionado Timer.Elapsed.

Existe outra maneira para obter uma referência a um objeto HttpServerUtility? Eu poderia injetá-lo na minha classe construtor. É seguro ? Como posso estar certo de que não vai ser lixo coletado no final da solicitação atual?

Obrigado!

Foi útil?

Solução

É possível usar HostingEnvironment.MapPath() vez de HttpContext.Current.Server.MapPath()

Eu não tentei ainda em um evento de thread ou temporizador embora.


Algumas soluções (não viáveis) Eu considerei;

  • O único método que me interessa em HttpServerUtility é MapPath. Assim como uma alternativa que eu poderia usar AppDomain.CurrentDomain.BaseDirectory e construir meus caminhos deste. Mas isso vai falhar se o seu aplicativo usa diretórios virtuais (Minas faz).

  • Outra abordagem: Adicione todos os caminhos que eu preciso para a classe do Global. Resolver esses caminhos em Application_Start.

Outras dicas

Eu não sei se isso vai resolver o seu problema diretórios virtual, mas eu uso isso 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('/', '\\');
}

HostingEnvironment não é a solução perfeita, porque é uma classe muito difícil de simulação (veja Como código de teste de unidade que usos HostingEnvironment.MapPath ).

Para aqueles que precisam a capacidade de teste, uma maneira melhor poderia ser a de criar sua própria interface caminho-mapeador como proposto por https: // stackoverflow .com / a / 1231962/85196 , exceto implementá-lo como

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

O resultado é facilmente mockable, usa HostingEnvironment internamente, e até poderia potencialmente endereço das ase69s preocupação ao mesmo tempo.

Você não pode chamar a função MapPath antes de iniciar o temporizador, e simplesmente armazenar em cache o resultado? É absolutamente neccessary para ter a chamada MapPath dentro do evento tick?

Quando o decorrer timer, não há contexto HTTP atual. Isso ocorre porque os eventos timer não estão relacionados a uma solicitação HTTP específica.

O que você deve fazer é usar HttpServerUtility.MapPath onde HTTP contexto está disponível. Você pode fazê-lo em um dos eventos de pedido de pipeline (como Page_Load) ou em um evento Global.asax como Application_Start.

Atribuir o resultado MapPath a uma variável acessível a partir do evento Timer.Elapsed, onde você poderia usar Path.Combine para obter a localização de um arquivo específico que você precisa.

Eu acho que a razão pela qual ele é nulo nesse momento (se você pensar sobre isso), é que o temporizador decorrido evento não ocorre como parte de uma solicitação HTTP (portanto, não há contexto). É causada por algo em seu servidor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top