programação assíncrona com c sharp

Post on 10-May-2015

286 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Programação assíncrona com C#

TRANSCRIPT

Programação assíncrona com C# 5André Bires @ Take.netJaneiro de 2014

Il Pizzeria Ritardato

Pizzeria Ritardato 5 garçons 10 mesas

Pizzeria Ritardato Garçom espera na cozinha o pedido

Pizzeria Ritardato + de 5 pedidos = Clientes esperando

Pizzeria Ritardato Contratação de + 5 garçons Total = 10

Pizzeria Ritardato Custo > Receita = Prejuízos

Il Pizzeria Veloce

Pizzeria Veloce 3 garçons 10 mesas

Pizzeria Veloce Garçom leva pedido na cozinha e volta para o balcão

Pizzeria Veloce Campainha Garçom pedido != garçom entrega

Pizzeria Veloce Aumento da freguesia 3 garçons + que suficientes Ampliação para 15 mesas

Pizzeria Veloce Mesmo custo com Maior receita = Maior eficiência

?

!

Programação assíncrona Uso eficiente dos recursos computacionais

NUNCA bloquear uma thread

Thread bloqueada = Dinheiro jogado fora

Thread bloqueada = Destruição da natureza

Programação assíncrona Retorno ao threadpool Notificação de conclusão

Não é o mesmo que programação paralela!

Programação assíncrona Pizzaria: Servidor Mesa/cliente: Aplicação Garçom: Thread Salário do garçom: Memória da

thread Balcão: Thread pool

Programação assíncrona Pedido: Requisição externa Pizzaiolo: Serviço externo Pizza: Resultado da requisição Campainha: Notificação

Programação assíncrona com C# 5

Programação assíncrona com C# Asynchronous Programming Model

(APM)

Programação assíncrona com C# Asynchronous Programming Model

(APM) Event-based Asynchronous Pattern

(EAP)

Programação assíncrona com C# Asynchronous Programming Model

(APM) Event-based Asynchronous Pattern

(EAP) Task-based Asynchronous Pattern (TAP)

Programação assíncrona com C# Asynchronous Programming Model

(APM) Event-based Asynchronous Pattern

(EAP) Task-based Asynchronous Pattern (TAP)

Task-based Asynchronous Pattern Task ou Task<T> C# 4 Task = Promisse ou Future

Task-based Asynchronous Pattern () => { } Threadpool

Task-based Asynchronous Pattern private void Example1Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    Task<string> task = Task.Run(() => GetName(1));

    nameTextBox.Text = task.Result;     toolStripStatusLabel.Text = "Done"; }

Task-based Asynchronous Pattern private void Example1Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    Task<string> task = Task.Run(() => GetName(1));

    nameTextBox.Text = task.Result;     toolStripStatusLabel.Text = "Done"; }

Task-based Asynchronous Pattern ContinueWith

Task-based Asynchronous Pattern private void Example2Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    Task.Run(() => GetName(1))     .ContinueWith(t =>         this.Invoke(new Action(() =>             {                 nameTextBox.Text = t.Result;                 toolStripStatusLabel.Text = "Done";             }))     );}

Task-based Asynchronous Pattern private void Example2Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    Task.Run(() => GetName(1))     .ContinueWith(t =>         this.Invoke(new Action(() =>             {                 nameTextBox.Text = t.Result;                 toolStripStatusLabel.Text = "Done";             }))     );}

Task-based Asynchronous Pattern private void Example2Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    Task.Run(() => GetName(1))     .ContinueWith(t =>         this.Invoke(new Action(() =>             {                 nameTextBox.Text = t.Result;                 toolStripStatusLabel.Text = "Done";             }))     );}

Task-based Asynchronous Pattern private void Example2Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    Task.Run(() => GetName(1))     .ContinueWith(t =>         this.Invoke(new Action(() =>             {                 nameTextBox.Text = t.Result;                 toolStripStatusLabel.Text = "Done";             }))     );}

Task-based Asynchronous Patternprivate void Example1Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    for (int i = 0; i < repeatNumericUpDown.Value; i++)     {         Task<string> task = Task.Run(() => GetName(1));         nameTextBox.AppendText(task.Result);         nameTextBox.AppendText(Environment.NewLine);     }

    toolStripStatusLabel.Text = "Done"; }

private void Example2Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";     GetNames(Convert.ToInt32(repeatNumericUpDown.Value));} private void GetNames(int remaining) {     Task.Run(() => GetName(1))         .ContinueWith(t =>             this.Invoke(new Action(() =>                 {                     nameTextBox.AppendText(t.Result);                     nameTextBox.AppendText(Environment.NewLine);                     remaining--;                     if (remaining > 0)                     {                         GetNames(remaining);                     }                     else                     {                         toolStripStatusLabel.Text = "Done";                     }                  })             )         ); }

Task-based Asynchronous Pattern C# 5.0 (.NET 4.5)

async

await

Task-based Asynchronous Pattern Método I/O que retorne uma Task Event handler assíncrono

Task-based Asynchronous Pattern private async void Example3Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";     nameTextBox.Text = await GetNameAsync(1);     toolStripStatusLabel.Text = "Done"; }

Task-based Asynchronous Patternprivate async void Example3Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";

    for (int i = 0; i < repeatNumericUpDown.Value; i++)     {         nameTextBox.AppendText(await GetNameAsync(1));         nameTextBox.AppendText(Environment.NewLine);     }     toolStripStatusLabel.Text = "Done"; }

Task-based Asynchronous Pattern private async void Example3Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";     nameTextBox.Text = await GetNameAsync(1);     toolStripStatusLabel.Text = "Done"; }

Task-based Asynchronous Pattern private async void Example3Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";     nameTextBox.Text = await GetNameAsync(1);     toolStripStatusLabel.Text = "Done"; }

Task-based Asynchronous Pattern private async void Example3Button_Click(object sender, EventArgs e) {     toolStripStatusLabel.Text = "Calling the API...";     nameTextBox.Text = await GetNameAsync(1);     toolStripStatusLabel.Text = "Done"; }

Primeiro estado

Segundo estado

Task-based Asynchronous Pattern

Overhead!

Task-based Asynchronous Pattern API verdadeiramente assíncronas = Completion port (Windows)

Task-based Asynchronous Pattern TcpClient HttpClient Socket Etc.

Task-based Asynchronous Pattern Async wrappers = EVIL

private Task<string> GetNameAsyncWrapper(int id){     return Task.Run(() =>     {         return GetName(id);     });}

private string GetName(int id) { // Synchronous implemementation }

Task-based Asynchronous Pattern

private Task<string> GetNameAsyncWrapper(int id){     return Task.Run(() =>     {         return GetName(id);     });}

private string GetName(int id) { // Synchronous implemementation }

Task-based Asynchronous Pattern

private async Task<string> GetNameAsync(int id) {     string url = string.Format("http://localhost:3803/names/{0}", id);     using (var client = new HttpClient())     {         var httpResponseMessage = await client.GetAsync(url);         if (httpResponseMessage.IsSuccessStatusCode)         {             return await httpResponseMessage.Content                 .ReadAsStringAsync();         }         else         {             return httpResponseMessage.ReasonPhrase;         }     } }

Task-based Asynchronous Pattern

Task-based Asynchronous Pattern Código legado requer muitas alterações

async =

infecção

public string Get(int id, bool delay = false){     if (delay)     {         // Simula uma chamada externa, como banco de dados         Thread.Sleep(3000);     }

    return string.Format(         "{0} {1}",         _firstNames[_random.Next(_firstNames.Length - 1)],         _lastNames[_random.Next(_lastNames.Length - 1)]); }

Task-based Asynchronous Pattern

public async Task<string> GetAsync(int id, bool delay = false) {     if (delay)     {         // Simula uma chamada externa, como banco de dados         await Task.Delay(3000);     }

    return string.Format(         "{0} {1}",         _firstNames[_random.Next(_firstNames.Length - 1)],         _lastNames[_random.Next(_lastNames.Length - 1)]); }

Task-based Asynchronous Pattern

Task-based Asynchronous PatternBoas práticas: async void apenas em event handlers ConfigureAwait(false) em bibliotecas

Task-based Asynchronous Pattern Callstack é diferente do código síncrono

?

top related