LINQ To SQL e Processamento Assíncrono do ASP.NET


escrevi e palestrei sobre a vantagem que temos ao fazer uso das páginas assíncronas, recurso que é fornecido a partir do ASP.NET 2.0.

Infelizmente o LINQ To SQL não possui intrinsicamente métodos para executar as queries de forma assíncrona e, sendo assim, não podemos incorporá-lo na execução assíncrona da página ASP.NET. Vale lembrar que voce pode criar um delegate apontando para um método, e dentro deste invocar as queries a partir do contexto do LINQ To SQL.

Utilizando esta técnica não trará os benefícios propostos pelas páginas assíncronas, pois quando voce invocar o delegate, ele extrairá uma thread do ThreadPool para executar a tarefa. A idéia das páginas assíncronas é fazer com que o processo custoso, como acesso a banco de dados, web services, etc., seja disparado através de uma thread de IO, liberando as threads do ThreadPool apenas para executar as páginas ASP.NET.

Para fazer o LINQ To SQL (ou qualquer outra tarefa) executar em uma thread de IO, podemos recorrer ao Power Threading, criada pela Wintellect. Essa library possui várias classes que nos auxiliam em tarefas assíncronas e, entre elas, temos a classe chamada CallbackThreadPool, que encapsula e gerencia a execução de tarefas a partir de threads de IO. Um único detalhe que precisamos nos atentar é a criação de um IAsyncResult customizado, que será utilizado pelo ASP.NET para determinar quando a query executada pelo LINQ To SQL for finalizada.

A parte mais complexa é a criação do IAsyncResult. Além da sua principal finalidade, ele também trará o resultado do processo assíncrono e possíveis exceções que essa tarefa possa disparar. Para facilitar e também conseguir reutilizar essa classe por várias entidades, eu a criei de forma genérica, trabalhando fortemente tipada. Para poupar espaço, abaixo consta apenas a sua definição.

public class DataAsyncResult<TResult> : IAsyncResult
{
    //implementação
}

A classe CallbackThreadPool fornece um método QueueUserWorkItem, e recebe como parametro uma instancia do delegate WaitCallback e da classe DataAsyncResult. O delegate deverá apontar para o método que irá executar a query via LINQ To SQL. O código abaixo ilustra como proceder para alistar um novo processo assíncrono através da Power Threading da Wintellect:

DataAsyncResult<IEnumerable<Cliente>> ar = new DataAsyncResult<IEnumerable<Cliente>>(callback, state);
_threadPool.QueueUserWorkItem(new WaitCallback(RecuperarDados), ar);

A partir deste ponto tudo é como já acontece normalmente com uma página assíncrona, ou seja, definindo o atributo Async da diretiva @Page como True e registrar a execução do processo assíncrono através do método AddOnPreRenderCompleteAsync da classe Page. Código de exemplo:

AsyncLINQToSQL.zip (39.97 kb)

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s