Desenvolvimento - ASP. NET
Turbine sua aplicação ASP.Net - Parte 3
Continuando a falar de performance o autor volta a tocar num assunto tão importante: Session State.
por Marcelo Menezes Neves
Continuando a falar de performance volto a tocar num assunto
tão importante: Session State. Você não consegue viver sem este recurso? Então aprenda
como utilizar Session State de maneira mais econômica. Você sabia que cada vez que
você solicita uma página de uma aplicação ASP.Net é enviado um request ao IIS e
este request "sofre" vários processamentos e que esta cadeia de processamento pode
ser otimizada? Bem, aqui vai mais um capítulo de um tão importante assunto no que
tange o desenvolvimento de sistemas - performance.
Session State ReadOnly
Você precisa usar , variáveis session? Ainda sim você pode otimizar, e muito, o uso delas. Por default sempre que você faz um request de uma página ASPX o IIS utiliza o objeto interno ReaderWriterLock para gerenciar a leitura e a escrita das variáveis session. Quando você atualiza o valor de uma variável session o objeto ReaderWriterLock bloqueia o acesso a variável, para poder atualizar seu valor, impedindo outros requests de escreverem e de lerem o valor da variável. E, geralmente, são feitas duas chamadas para cada request: uma chamada para bloquear a variável session e executar a página, e uma segunda chamada para alterar e desbloquear a variável session.
Este processo pode ser otimizado! Imagine que você tem um webform que somente lê as variáveis. Se você deixar que a configuração padrão, que é EnableSessionState="true", acontecerá exatamente como acabei de explicar, será feito um bloqueio para ler e atualizar a variável e, logo depois, um desbloqueio das variáveis, mesmo que o webform somente leia as variáveis. Mas, se você alterar o valor do atributo EnableSessionState para ReadOnly este bloqueio não ocorrerá, pois será informado ao IIS que aquela página somente irá ler as variáveis. Para alterar o valor deste atributo da diretiva PAGE edite o código HTML da página ASPX e altere o valor do parâmetro conforme mostrado abaixo:
<%@ Page EnableSessionState="ReadOnly" %>
Fazendo isso, além de evitar que as variáveis session sejam bloqueadas, pelo objeto ReaderWriterLock, o IIS permitirá requests concorrentes e, consequentemente, você perceberá maior velocidade no tempo de resposta de sua aplicação.
Otimize o HTTP Pipeline
Cada vez que você chama uma página ASPX no browser, é enviado um request HTTP para o IIS, e este passa por uma série de estágios de processamento, que nada mais são que HTTP modules, que juntos formam o HTTP pipeline do ASP.Net. Cada um dos módulos, ou estágios, do HTTP pipeline, oferece um diferente tipo de serviço, como por exemplo: serviços de autenticação, session state e etc. Quanto mais estágios existirem, maior será o caminho a ser percorrido pelo request e, portanto, maior será o tempo de resposta. Portanto a dica é a seguinte: elimine todos os estágios desnecessários.
Para verificar quais módulos compõe o HTTP pipeline abra o machine.config e localize o nó <httpModules>. Veja no exemplo abaixo um exemplo de como está configurado o HTTP pipeline:
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>
</httpModules>
No exemplo acima, repare os módulos que compõe o HTTP pipeline. Se por acaso sua aplicação não usa Forms Authentication, você deve retirar o elemento <add name="FormsAuthentication">, evitando que cada request passe pelo HTTP module responsável por tal recurso. Para retirar o HTTP module, e dessa maneira otimizar o HTTP pipeline, comente a chamada para o HTTP module em questão da seguinte forma:
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
<!-- <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/> -->
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>
</httpModules>
Faça isso com todos os HTTP modules que oferecem recursos os quais você não utiliza. Você perceberá um grande ganho de performance no tempo de resposta de sua aplicação ASP.Net.
Libere os recursos consumidos
Enquanto estamos codificando nem sempre nos apercebemos,
mas estamos utilizando recursos limitados e, portanto, saber utilizá-los pode representar
um diferencial no resultado final de nossas aplicações. Por exemplo, num procedimento
onde abrimos uma conexão com o banco de dados e criamos um datareader, vários objetos
são criados consumindo recursos e que, assim que não mais precisarmos deles, necessitam
ser liberados para o sistema.
No caso de variáveis do tipo objeto a Microsoft recomenda nular explicitamente as
variáveis e, para alguns objetos quando disponível, realizar o dispose. O exemplo
abaixo mostra como você deve fazer isso para as variáveis objeto do tipo sqldatareader,
sqlcommand e sqlconnection. O mesmo vale para todas as variáveis objeto. E nem é
preciso dizer, mas o lugar mais seguro para fazermos isso é colocar este de código
no Finally pois será obrigatoriamente executado, independente
da aplicação gerar uma exceção ou não.
Private Sub Pesquisar() Try Catch ex2 As Exception Finally "Datareader If Not IsNothing(drdPesquisa) Then If Not drdPesquisa.IsClosed Then drdPesquisa.Close() drdPesquisa = Nothing End If "Command If Not IsNothing(cmdPesquisa) Then cmdPesquisa.Dispose() cmdPesquisa = Nothing End If "Connection If Not IsNothing(conPesquisa) Then If conPesquisa.State = ConnectionState.Open Then conPesquisa.Close() conPesquisa.Dispose() End If End Try End Sub
Bem meus amigos, continuarei a falar mais sobre performance nos próximos artigos dando continuidade a esta série. Possivelmente devo iniciar também uma nova série falando de performance, é claro, mas agora voltado para o ADO.Net. Em breve também falarei sobre como funciona uma aplicação ASP.Net no IIS 6.0. Essa tem sido uma das grandes questões entre os desenvolvedores e, portanto, darei atenção ao assunto.
Até o próximo artigo!