apm model in .net - pt-pt

8
Modelo APM em .NET por Pedro Gabriel O porquê da utilização/necessidade de uma abordagem assíncrona : Esta necessidade surge devido, principalmente à evolução das arquitecturas que passaram a ser multi-core em vez de single-core. Anteriormente, quando falávamos em aplicações “escaláveis”, qualquer aplicação single-thread era escalável num ambiente single-core, uma vez que todos os melhoramentos feitos aos processadores da época eram baseados numa melhor performance em single-core. Com o aparecimento de arquitecturas multi-core, qualquer aplicação single-thread deixou de ser escalável, pois não tira partido das funcionalidades das novas arquitecturas. Por suas vez, as linguagens de programação evoluiram de tal forma que praticamente todas as linguagens de alto nível suportam este tipo de abordagem, dando assim a possibilidade do programador criar aplicações multi-thread. Principais diferenças entre “modelos”: Normalmente, perante programas single-thread o fluxo de actividades pode ser descrito da seguinte forma: Estamos então, na presença de acções sequênciais, que mesmo sendo independentes ou não, só serão executadas consoante a ordém disposta. 1

Upload: pedro-de-almeida

Post on 20-Jul-2015

44 views

Category:

Education


0 download

TRANSCRIPT

Page 1: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

O porquê da utilização/necessidade de uma abordagem assíncrona :

Esta necessidade surge devido, principalmente à evolução das arquitecturas que

passaram a ser multi-core em vez de single-core. Anteriormente, quando falávamos em aplicações “escaláveis”, qualquer aplicação single-thread era escalável num ambiente single-core, uma vez que todos os melhoramentos feitos aos processadores da época eram baseados numa melhor performance em single-core. Com o aparecimento de arquitecturas multi-core, qualquer aplicação single-thread deixou de ser escalável, pois não tira partido das funcionalidades das novas arquitecturas. Por suas vez, as linguagens de programação evoluiram de tal forma que praticamente todas as linguagens de alto nível suportam este tipo de abordagem, dando assim a possibilidade do programador criar aplicações multi-thread.

Principais diferenças entre “modelos”:

Normalmente, perante programas single-thread o fluxo de actividades pode ser descrito da seguinte forma:

Estamos então, na presença de acções sequênciais, que mesmo sendo independentes ou não, só serão executadas consoante a ordém disposta.

1

Page 2: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

No que toca a um programa multi-thread, podemos descrever o fluxo de acções da seguinte forma: Por esta ordem de ideias, cada acção é executada por uma Thread diferente, deixando ao programador a gestão do fluxo do seu programa conforme o tempo que cada acção pode levar a ser completada. Com esta abordagem, está implicito um overhead que pode ser criado se uma aplicação tiver mais Threads do que processadores lógicos para uma determinada máquina. Tipicamente, estes custos podem ser descritos da seguinte forma:

● Custos Estáticos: Estão associados à memória utilizada para conter estruturas de dados relativas às Threads, e ao espaço de endereçamento alocado. Proporcional ao número de Threads.

● Custos Dinâmicos: Associados à actividade de scheduling. Quantas mais Threads estiverem em execução - READY - maior será a actividade de Scheduling. Proporcional ao número de Threads “Ready” para além do nº de cores.

A este modelo está ainda adjacente a necessidade de implementar mecanismos de sincronização de Threads relativamente ao acesso a dados, por forma a manter os mesmos no estado correcto.

2

Page 3: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

Por último, resta demonstrar o fluxo de uma abordagem/modelo assíncrono. Neste modelo, as ações são executadas de forma intercalada, com a gestão realizada apenas por uma Thread. Uma das grandes vantagens deste modelo, é o facto de o programador poder dar “ordens” às ações a realizar. Do ponto de vista do segundo modelo (multi-thread), ações podem ser interrompidas consoante o “desejo” do Sistema Operativo. Neste último modelo é o programador quem pode dar ordem de interrupção, mantendo assim o controlo sobre as ações.

3

Page 4: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

Após a descrição da motivação para o uso de programação assíncrona e uma breve descrição dos modelos mais utilizados, vejamos agora um modelo concreto que foi o principal padrão utilizado pela framework .NET antes da versão 4.5. Este documento mostra ainda os três tipos de rendezvous que integram o APM: Wait-Until Done, Polling, Callback.

Asynchronous Programming Model (APM): Este padrão permite-nos executar várias ações em diferentes Threads. Várias classes da framework .NET suportam este padrão através do fornecimento de métodos que seguem a cnvenção BeginXXX e EndXXX. Para demonstrar este mesmo padrão, iremos utilizada o método Read da classe Stream. Primeiro, vejamos a versão sincrona:

public int Read (byte[] buffer, int offset, int size);

De seguida, a versão que suporta APM: public IAsyncResult BeginRead (byte[] buffer, int offset, int size, AsyncCallback callback, object state);

public int EndRead (IAsyncResult asyncResult);

Outra particularidade é o tipo de retorno que está envolvido nestes métodos da versão APM. O método que inicia a operação (Begin) devolve um objecto do tipo IAsyncResult que, basicamente, é um token que representa a operação. Existe também um callback, que é basicamente uma função que será executada mediante certas condições. Neste caso concreto, este callback só é executado quando a operação assíncrona termina ou quando ocorre um erro na sua realização. A definição do callback é dada pelo seguinte delegate:

public delegate void AsyncCallback (IAsyncResult ar);

Quem tratar deste callback/delegate invoca o método que devolve o resultado final da operação assíncrona (End). É também responsável por re-lançar um erro caso este ocorra.

4

Page 5: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

Vejamos então código-fonte que demonstra este padrão: É de notar então, que na construcção do objecto do tipo FileStream é necessária a indicação da intenção futura de realizar uma leitura assíncrona. De modo a realizar a leitura deste mesmo modo, são invocados os métodos que suportam a versão APM, BeginRead e EndRead. O primeiro recebe todos os argumentos que o método Read recebe, e mais dois que efectuam o suporte ao modelo APM - Callback e Object-State. Note-se ainda o retorno de uma objecto IAsyncResult que é posteriormente passado ao método End para obter o resultado final.

5

Page 6: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

Rendezvous 1 - Wait-Until Done: Este tipo de rendezvous permite iniciar uma acção assíncrona, realizar outro trabalho, e posteriormente voltar para verificar se a acção foi completada entretanto. A verificação irá bloquear até que a acção seja completada.

Percebemos então que, qualquer código que seja colocado entre as chamas dos métodos APM será executado enquanto o mesmo pedaço de código lê o ficheiro de texto. É uma abordagem possivel para aplicações que pretendam ter um grau de resposta alto perante um elevado número de acções a realizar.

6

Page 7: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

Rendezvous 2 - Polling : Este tipo de rendezvous envolve a Thread que pretende ser notificada directamente, ou seja, é esta que tem de verificar, ao longo de um periodo, a realização da acção assíncrona que iniciou. Tem a vantagem de não bloquear enquanto realiza as verificações. A verificação é feita através da chamada da propriedade de IsComplete do resultado devolvido pelo método BeginXXX. Código acima demonstra que, é possivel realizar outro trabalho, à medida que se verifica a realização da acção inicial, sem que esta bloqueie a Thread envolvida.

7

Page 8: APM Model in .NET - PT-pt

Modelo APM em .NET por

Pedro Gabriel

Rendezvous 3 - Callback : Este último rendezvous obriga à passagem de um método callback que será executado quando a acção assíncrona terminar ou se gerar erro. É desta forma que ficamos a saber que a acção terminou. Por esta lógica, é dentro do callback que iremos obter o resultado final da nossa acçao assíncrona, através do método EndXX. Na prática, o que o método BeginXX está a fazer é colocar a acção assíncrona numa fila de acções (queue), que através de Threads mantidas pela ThreadPool internal do .NET, será realizada mais tarde. A forma que a framework tem de avisar a Thread que iniciou a acção é invocar o callback fornecido pela Thread inicial. Se o callback for: Então a chamada será feita da seguinte forma:

fs.BeginRead(s_data, 0, s_data.Length, ReadIsDone, fs);

Como podemos ver, a obtenção do resultado é feita dentro do callback. O mesmo resultado é tratado lá dentro, uma vez que não é permitido qualquer retorno. Relembro que a assinatura do método tem que satisfazer o delegate demonstrado anteriormente.

8