Silverlight e a chamada assíncrona de serviços


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.

Anúncios

3 comentários sobre “Silverlight e a chamada assíncrona de serviços

  1. 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!

    • 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.

    • 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.

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