Demonstra Passo a passo: Criar um manipulador HTTP assíncrono
Essa explicação passo a passo mostra como criar um manipulador HTTP assíncrono.Manipuladores assíncronos HTTP permitem que você inicie um processo externo (como uma chamada de método a um servidor remoto) enquanto o manipulador continua o processamento.O manipulador pode continuar sem esperar que o processo externo concluir.
Durante o processamento de um manipulador HTTP assíncrono, ASP.NET coloca o segmento que normalmente deve ser usado para o processo externo de volta para o pool de segmento até o manipulador receber um retorno de chamada do processo externo.Isso pode prevenir que o segmento bloqueie e melhora bastante o desempenho, porque somente um número limitado de segmentos podem ser executados simultaneamente.Rapidamente se um número de usuários solicitar manipuladores HTTP síncronos que dependam dos processos externos, o sistema operacional pode executar fora de segmentos pois muitos segmentos são bloqueados e ficam em espera por um processo externo.
O exemplo nessa explicação passo a passo demonstra um manipulador HTTP assíncrono que processa solicitações de arquivos que possuem extensão de nome de arquivo .SampleAsync em um aplicativo ASP.NET.O exemplo mostra o código para o manipulador e, em seguida, como MAP a extensão .SampleAsync para o manipulador no ASP.NET.O exemplo também mostra como mapear a extensão .SampleAsync para o ASP.NET no IIS, para que IIS encaminhe solicitações participante no .SampleAsync para o ASP.NET.
Para obter mais informações sobre como a execução em ASP.NET interage com o IIS 6.0, consulte Ciclo de Vida do Aplicativo ASP.NET uma visão geral para o IIS 5.0 e 6.0.Para obter mais informações sobre a integração do ASP.NET com IIS 7.0, consulte Uma visão geral do Ciclo de Vida do Aplicativo ASP.NET para o IIS 7.0.
Tarefas ilustradas nesta explicação passo a passo incluem o seguinte:
Como criar o código para uma classe manipulador HTTP.A classe deve implementar o método ProcessRequest e a propriedade IsReusable.
Como registrar o manipulador no arquivo Web.config e mapear a extensão de nome de arquivo .sample para ele.
Como mapear a extensão de nome de arquivo .Sample do ASP.NET no IIS.
Pré-requisitos
A fim de concluir este explicação passo a passo, será necessário:
Visual Studio ou Visual Web Developer.
Um site da Web ASP.NET que possa ser executado por meio do IIS.
IIS 6.0 ou IIS 7.0.
Criar uma classe de manipulador HTTP síncrono
Para começar, você criará uma classe que implementa o manipulador assíncrono.
Para criar a classe de um manipulador HTTP HelloWorldAsyncHandler
Se o site da Web em que você estiver trabalhando ainda não tiver uma pasta App_Code, crie uma na raiz do site.
Na pasta App_Code, crie uma classe denominada HelloWorldAsyncHandler e adicione o código a seguir ao arquivo da classe.
Imports Microsoft.VisualBasic Imports System.Web Imports System.Threading Public Class HelloWorldAsyncHandler Implements IHttpAsyncHandler Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable Get Return False End Get End Property Public Function BeginProcessRequest( _ ByVal context As System.Web.HttpContext, _ ByVal cb As System.AsyncCallback, _ ByVal extraData As Object) _ As System.IAsyncResult _ Implements System.Web.IHttpAsyncHandler.BeginProcessRequest context.Response.Write("<p>Begin IsThreadPoolThread is " _ & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) Dim asynch As New AsynchOperation(cb, context, extraData) asynch.StartAsyncWork() Return asynch End Function Public Sub EndProcessRequest(ByVal result As _ System.IAsyncResult) _ Implements System.Web.IHttpAsyncHandler.EndProcessRequest End Sub Public Sub ProcessRequest(ByVal context _ As System.Web.HttpContext) _ Implements System.Web.IHttpHandler.ProcessRequest Throw New InvalidOperationException() End Sub End Class Class AsynchOperation Implements IAsyncResult Private _completed As Boolean Private _state As [Object] Private _callback As AsyncCallback Private _context As HttpContext ReadOnly Property IsCompleted() As Boolean _ Implements IAsyncResult.IsCompleted Get Return _completed End Get End Property ReadOnly Property AsyncWaitHandle() As WaitHandle _ Implements IAsyncResult.AsyncWaitHandle Get Return Nothing End Get End Property ReadOnly Property AsyncState() As [Object] _ Implements IAsyncResult.AsyncState Get Return _state End Get End Property ReadOnly Property CompletedSynchronously() As Boolean _ Implements IAsyncResult.CompletedSynchronously Get Return False End Get End Property Public Sub New(ByVal callback As AsyncCallback, _ ByVal context As HttpContext, _ ByVal state As [Object]) _callback = callback _context = context _state = state _completed = False End Sub Public Sub StartAsyncWork() ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf StartAsyncTask), Nothing) End Sub Private Sub StartAsyncTask(ByVal workItemState As [Object]) _context.Response.Write("<p>Completion IsThreadPoolThread is " & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) _context.Response.Write("Hello World from Async Handler!") _completed = True _callback(Me) End Sub 'StartAsyncTask End Class 'AsynchOperation
using System; using System.Web; using System.Threading; class HelloWorldAsyncHandler : IHttpAsyncHandler { public bool IsReusable { get { return false; } } public HelloWorldAsyncHandler() { } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); AsynchOperation asynch = new AsynchOperation(cb, context, extraData); asynch.StartAsyncWork(); return asynch; } public void EndProcessRequest(IAsyncResult result) { } public void ProcessRequest(HttpContext context) { throw new InvalidOperationException(); } } class AsynchOperation : IAsyncResult { private bool _completed; private Object _state; private AsyncCallback _callback; private HttpContext _context; bool IAsyncResult.IsCompleted { get { return _completed; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } } Object IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { return false; } } public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) { _callback = callback; _context = context; _state = state; _completed = false; } public void StartAsyncWork() { ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null); } private void StartAsyncTask(Object workItemState) { _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); _context.Response.Write("Hello World from Async Handler!"); _completed = true; _callback(this); } }
No código da página, chame o método BeginProcessRequest.O método grava uma sequência de caracteres para a propriedade Response do objeto atual HttpContext, cria uma nova instância da classe AsyncOperation e chama o método StartAsyncWork.O método StartAsyncWork em seguida adiciona o delegado StartAsyncTask ao objeto ThreadPool.Quando um segmento estiver disponível, o método StartAsyncTask é chamado, no qual gravará outra sequência de caracteres para a propriedade Response.A tarefa então termina invocando o delegado AsyncCallback.
Registrando o manipulador HTTP personalizado no IIS 6,0
Depois de criar a classe manipulador HTTP personalizada, você deve registrá-la no arquivo Web.config do aplicativo.Isso permite que o ASP.NET localize o manipulador quando as solicitações são feitas para os recursos cujo URL termina com .SampleAsync.
Há procedimentos diferentes para registrar o manipulador, dependendo se você estiver trabalhando com o IIS 6.0 ou IIS 7.0.Esta seção descreve como registrar um manipulador no IIS 6.0.A próxima seção descreve como registrar um manipulador no IIS 7.0.
Para registrar o manipulador no IIS 6.0
Se o site da Web ainda não tiver um arquivo Web.config, crie um na raiz do site.
Adicione a seguinte marcação realçada para o arquivo Web.config:
<configuration> <system.web> <httpHandlers> <add verb="*" path="*.SampleAsync" type="HelloWorldAsyncHandler"/> </httpHandlers> </system.web> </configuration>
O elemento de configuração registra o HelloWorldAsyncHandler manipulador de sistema autônomo o manipulador de solicitações que finaliza SampleAsync.
Registre um mapeamento de extensão do aplicativo para a extensão de nome de arquivo .SampleAsync usando Gerenciador do IIS.Para obter mais informações, consulte Como: Configurar uma extensão de manipulador HTTP no IIS.
Registrando o manipulador HTTP personalizado no IIS 7.0
No IIS 7.0, um aplicativo pode executar no modo Clássico ou no modo Integrado.No modo Clássico, as solicitações são processadas da mesma maneira como eles estão no IIS 6.0.No modo integrado, IIS 7.0 gerencia solicitações usando um pipeline que permite que ele compartilhe as solicitações, módulos e outros recursos com o ASP.NET.
Para IIS 7.0, o registro do manipulador requer o registro do manipulador no arquivo Web.config ou no Gerenciador do IIS.Devido a administração centralizada no IIS 7.0, as alterações no arquivo Web.config do aplicativo são refletidas na interface Gerenciador do IIS para o aplicativo e vice-versa.Nos procedimentos a seguir, os manipuladores são registrados no arquivo Web.config.
Há procedimentos diferentes para registrar o manipulador IIS 7.0 sendo executado no modo Clássico e sendo executado no modo Integrado.Siga o procedimento para o modo IIS que você está usando.
Para registrar o manipulador no IIS 7.0 executando no modo clássico
Se o site da Web ainda não tiver um arquivo Web.config, crie um na raiz do site.
Adicione o seguinte elemento realçado ao arquivo Web.config.
Observação: Substitua o caminho correto do arquivo aspnet_isapi.dll.O arquivo .dll está na pasta onde o .NET Framework está instalado.Por padrão, é C:\WINDOWS\Microsoft.NET\Framework\versão.
<configuration> <system.web> <httpHandlers> <add verb="*" path="*.SampleAsync" type="HelloWorldAsyncHandler"/> </httpHandlers> </system.web> <system.webServer> <handlers> <add verb="*" path="*.SampleAsync" name="HelloWorldAsyncHandler" type="HelloWorldAsyncHandler" modules="IsapiModule"/> scriptProcessor="%path%\aspnet_isapi.dll" </handlers> </system.webServer> </configuration>
O elemento de configuração registra o manipulador personalizado pelo nome da classe, e ele mapeia a extensão de nome de arquivo .SampleAsync a esse manipulador.
Observação: Porque você estiver inscrevendo uma extensão de nome de arquivo personalizada, você registra o manipulador tanto na seção handlers como na seção httpHandlers.No modo Clássico, para compatibilidade com versões anteriores, o manipulador é especificado como um módulo ISAPI usando o atributo modules.O caminho da DLL ISAPI do ASP.NET é especificado usando o atributo scriptProcessor.O atributo name é necessário na seção handlers.
Para registrar o manipulador no IIS 7.0 executando no modo Integrado
Se o site da Web ainda não tiver um arquivo Web.config, crie um na raiz do site.
Adicione o seguinte elemento realçado ao arquivo Web.config.
<configuration> <system.webServer> <handlers> <add verb="*" path="*.SampleAsync" name="HelloWorldAsyncHandler" type="HelloWorldAsyncHandler"/> </handlers> </system.webServer> </configuration>
O elemento de configuração registra o manipulador personalizado pelo nome da classe, e ele mapeia a extensão de nome de arquivo .SampleAsync a esse manipulador.
Observação: O registro é feito na seção handlers, e não na seção httpHandlers.O atributo name é necessário.
Teste o manipulador HTTP personalizado
Depois de ter criado e registrado o manipulador HTTP personalizado, você pode testá-lo.
Para testar o manipulador HTTP personalizado
Navegue até o aplicativo e digite uma URL em um navegador que termina em .SampleAsync.
O texto definido na classe HelloWorldAsyncHandler é exibido.
Consulte também
Tarefas
Passo-a-Passo: Criando um Manipulador HTTP Síncrono
Conceitos
Ciclo de Vida do Aplicativo ASP.NET uma visão geral para o IIS 5.0 e 6.0