Silverlight e a chamada assíncrona de serviços

by Israel Aece 22. June 2010 23:47

Em geral, podemos consumir os serviços WCF de duas formas: síncrona ou assíncrona. Na primeira opção, ao referenciar o serviço em uma aplicação cliente e invocar um das operações que ele disponibiliza, a comunicação será realizada e enquanto ela não retorna, a aplicação ficará bloqueada aguardando o resultado. Já no segundo modelo, ao realizar a chamada de forma assíncrona, a operação será realizada em um thread secundária, permitindo que a aplicação continue trabalhando enquanto o serviço é executado.

Como sabemos, o Silverlight tem cada vez mais espaço como sendo front-end de aplicações. Essa tecnologia recorre à serviços quando precisa buscar algum conteúdo remoto, como por exemplo, preencher os dados em um controle ListBox quando um botão for pressionado. Atualmente, a maioria desses serviços são construídos em WCF, e referenciados na aplicação Silverlight para permitir que a mesma interaja com o servidor para extrair os dados necessários para executar o seu trabalho.

Para aqueles que já utilizam essa técnica, já devem ter percebido que no Silverlight, só podemos consumir esses serviços de forma assíncrona, ou seja, recorrendo à uma segunda thread através do par de métodos BeginXXX/EndXXX ou através de eventos. Mas porque isso acontece ou porque é necessário?

O Silverlight possui apenas uma única thread, que é chamada de UI Thread, e como sabemos, operações de I/O bound, como é o caso da comunicação através da rede, são tarefas custosas e que podem levar um grande tempo para ser executada, e justamente por isso, se o Silverlight bloqueasse a thread de UI enquanto executa essa requisição, o host (que é o navegador), também seria bloqueado. Mesmo que você tente emular uma chamada síncrona, utilizando algum recurso primitivo de sincronização (como o ManualResetEvent), você teria problemas do mesmo jeito, já que quando invocar o método WaitOne desta classe, ele bloqueará a thread de UI para esperar o resultado, que nunca chegará, pois o resultado somente será entregue para o Silverlight quando a thread de UI não estiver executando nenhum código, que não é o caso aqui, e como já era de se esperar, teremos um deadlock.

Desde o proxy de serviços WCF até classes de baixo nível, como é o caso da WebClient, terão o mesmo comportamento, ou seja, deverão ser sempre acionadas através do modelo assíncrono. Tudo isso se deve ao fato de que os navegadores atuais implementam a NPAPI (Netscape Plugin Application Programming Interface). A NPAPI trata-se de uma API multi-plataforma desenvolvida pela Netscape que permite que plugins sejam utilizados dentro dos navegadores. Para que os plugins sejam considerados multi-plataforma, eles precisam seguir rigorosamente essa API, o que determina que métodos remotos sejam executados assincronamente, e como já percebemos, o Silverlight segue o que foi definido por ela.

Tags: ,

Async | WCF

Comments

6/23/2010 12:39:58 AM #

pingback

Pingback from topsy.com

Twitter Trackbacks for
        
        Israel Aece | Silverlight e a chamada assíncrona de serviços
        [israelaece.com]
        on Topsy.com

topsy.com

6/23/2010 10:53:41 AM #

Márcio Fábio Althmann

É, lembro quando conversei com você sobre isso Smile.
Valeu Israel, ótimo post.

Abraços.

Márcio Fábio Althmann Brazil

6/23/2010 8:38:34 PM #

Ari C. Raimundo

Israel,

Somente assisti a alguns vídeos à respeito e não conheço muito bem, mas no caso do WCF RIA Services existem algumas operações que aparentemente parecem ser síncronas. Como funciona essas chamadas nesse framework?

Ótimo post.

Ari C. Raimundo Brazil

6/23/2010 9:10:29 PM #

IsraelAece

Boas Ari,

Sabe me dizer exatamente o que? Tem algum exemplo?

IsraelAece Brazil

6/24/2010 10:13:21 AM #

Ari C. Raimundo

Olá Israel,

Veja o exemplo desse link http://bit.ly/90jWEy. Como eu disse essas operações "aparentemente" parecem ser síncronas. Veja que não foi necessário os pares BeginXXX/EndXXX ou até mesmo um XXXAsync/XXXCompleted. Existe algo no DomainContext que encapsula essa chamada assíncrona?

Obs: Como eu disse não conheço muito bem o WCF RIA Services.

Um abraço.

Ari C. Raimundo Brazil

6/24/2010 2:09:16 PM #

IsraelAece

Boas Ari,

Aparentemente, você tem razão, já que invocamos o método Load sem ver explicitamente o processo assíncrono.

Na verdade, toda a complexidade está abstraída pela classe DomainContext. Internamente, em um overload específico deste mesmo método, você notará que ele criará e retornará a instância de uma classe do tipo LoadOperation.

Essa classe recebe a query a ser disparada e, internamente, faz uso de uma terceira classe, chamada de DomainClient, que expõe dois métodos autoexplicativos: BeginQuery e EndQuery, que são utilizados para realizar o processamento (query) assincronamente.

Definimos o DataSource de um controle com a propriedade Entities da LoadOperation, que retorna a instância de uma coleção do tipo ObservableCollection<T>, com as itens da serão/foram retornados pela query. A classe LoadOperation implementa indiretamente a interface INotifyPropertyChanged, que como sabemos, notifica de que alguma propriedade dentro dela foi alterada. Com isso, o controle será notificado da mudança, e irá recarregar o mesmo.

IsraelAece Brazil

6/24/2010 2:33:02 PM #

Ari C. Raimundo

Entendi, a implementação da interface INotifyPropertyChange é que propiciou o controle ser atualizado após o término da query.

Verifiquei na documentação que a classe DomainClient possui vários métodos BeginXXX/EndXXX. Bem interessante!

Obrigado pela explicação.
Um abraço!

Ari C. Raimundo Brazil

Comments are closed

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Host