SlideShare uma empresa Scribd logo
1 de 4
Baixar para ler offline
De Síncron a Asíncron
El que pretenc en aquest document és mostrar de manera senzilla com passar d'un mètode síncron a
un asíncron. Per fer-ho utilitzaré una petita aplicació Winforms amb un formulari que conté un botó
i una etiqueta. Simularem que quan premem el botó executa un mètode que conta el número de
registres que hi ha en un repositori de dades d'exemple, i el resultat el pinta en l'etiqueta. El que
farem és posar el codi del event del botó, primer de manera síncrona, i després de manera
asíncrona, utilitzant tècniques diferents, segons el framework de .NET.

(El projecte l'adjuntaré al final de tot del document.)

Un cop creat el projecte i el formulari, en centrem en el codi principal.




Mètode Síncron

/// <summary>
/// Versió síncrona
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
      label1.Text =
          RepositoryExample.CountExamples().ToString();
}

namespace ConvertSyncToAsync
{
      public class RepositoryExample
      {
             public static int CountExamples()
             {
                   System.Threading.
Thread.Sleep(5000);
                          return 10000;
                 }
      }
}

En el primer requadre tenim el codi que s'executa quan premem el botó. I en el requadre de sota el
codi que simula el repositori.

Quan executem en aquest context ens trobem que mentre s'executa l'acció, el formulari queda com
bloquejat, i no podem fer res amb ell, ni moure'l. Això pot provocar desconcert en l'usuari que la fa
servir, i pot pensar que l'aplicació ha deixat de funcionar si dura molt.

Mètode Asíncron 1

En versions anteriors al .NET 4.0, per executar mètodes de manera asíncrona podíem fer servir
Threads, delegats i en winforms el BackGroundProcess, els quals no recomano, ja que s'ha
demostrat que la seva eficiència deixa molt a desitjar. En el exemple que us poso faré servir
delegats, ja que d' una manera molt senzilla tenim un resultat molt òptim.

/// <summary>
/// Versió asíncrona 1. Versions anteriors a .NET 4.0
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
  Func<int> CountExamples = () => RepositoryExample.CountExamples();
    CountExamples.BeginInvoke((result) =>
      {
       var data = (result.AsyncState as Func<int>).EndInvoke(result);
       this.Invoke(new Action(() => label1.Text = data.ToString()));
       }, CountExamples);
}

Si executem ara amb aquest codi veurem clarament que la interfície respon mentre executa el
procés de l´event de butó. Només cal intentar moure-la. Hem de tenir en compte però, que quan
executem en threads diferents, des d'un thread no és pot accedir a components de l'altre
directament. Els controls del formulari han estat creats per el thread del procés de la interfície,
mentre que el delegat s'executa en un altre thread. Si des d'aquet volguéssim accedir a la label
directament ens donaria un excepció. Per això cal invocar una acció des del thread principal del UI
que contingui el codi que volem executar sobre el component.

Mètode Asíncron 2

En la versió 4 del framework, es van introduir les Tasques (Task) com a classes (juntament amb altres
del namespace) que ajuden a la programació asíncrona. La veritat es que van molt bé. Solucionen
d'una manera molt planera l'execució asíncrona i la sincronització amb el context d'altres fils
d'execució, com pot ser el cotext principal des d'on s'inicien el processos de negoci, en el nostre cas
el procés del UI.

/// <summary>
/// Versió asíncrona 2. .NET 4.0. Introducció de les Tasques
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
        var task = Task<int>.Factory.StartNew(() =>
RepositoryExample.CountExamples());
        task.ContinueWith((result) => label1.Text =
result.Result.ToString(),
             TaskScheduler.FromCurrentSynchronizationContext());
}

El resultat és el mateix en tots els casos. Però amb l'aparició de les tasques i tot el que les envolta, fa
que la programació asíncrona et sigui més fàcil d'implementar així, que no pas amb threads o
delegats. Si no poséssim el paràmetre

              TaskScheduler.FromCurrentSynchronizationContext()

donaria una excepció al intentar accedir des d'un fil a fil de UI per fer l'assignació a la label. Aquest
instrucció fa que es sincronitzi el fil al el context de l'UI.

Mètode Asíncron 3

Amb la introducció del framework 4.5 han aparegut dues instruccions o declaracions que fan
referència explícita a la programació asíncrona. El async i el await. El primer va en la declaració del
mètode i indica que aquest és asíncron. El segon precedeix la execució d'un procés, i d'alguna
manera li diu que s'executi quan no molesti a ningú. És una aportació molt important al framework
(com altres) que cal estudiar molt bé, ja que millora molt els resultats. Van de la maneta de les
tasques com podem observar en el codi.

/// <summary>
/// Versió asíncrona 3. .NET 4.5. Introducció del async i await
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button1_Click(object sender, EventArgs e)
{
var result = await RepositoryExample.CountExamplesAsync();
label1.Text = result.ToString();
}

namespace ConvertSyncToAsync
{
  public class RepositoryExample
  {
    public static int CountExamples()
     {
        System.Threading.Thread.Sleep(5000);
        return 10000;
     }
    public static Task<int> CountExamplesAsync()
     {
        return Task.Factory.StartNew<int>(() =>
         {
System.Threading.Thread.Sleep(5000);
               return 10000;
            });
        }
    }
}

Si ens hi fixem l'event del botó ja el marquem com asíncron. La funció del repositori per poder-la
invocar amb un await cal que el tipus de retorn sigui un Task. I un cop dintre l'únic que fem es
executar una tasca. En el UI tractem el procés com si fos síncron, el marquem com asíncron async i
esperem les operacions internes asíncrones amb el await.



Fins aquí la petita introducció. Recomano estudiar molt el tema juntament amb l'execució en
paral·lel. No serveix de res tenir més d'un core als ordinadors, si el programes no els fan servir.




                                                                                        @SOACAT

                                                                       http://soacat.blogspot.com

Mais conteúdo relacionado

Destaque

Hs303 sadfs@sad..asd:\][
Hs303 sadfs@sad..asd:\][Hs303 sadfs@sad..asd:\][
Hs303 sadfs@sad..asd:\][
Anil Shanbhag
 
Warum männer früher sb
Warum männer früher   sbWarum männer früher   sb
Warum männer früher sb
fink2fink2
 
Hochschul-Marketing & -Rekrutierung
Hochschul-Marketing & -RekrutierungHochschul-Marketing & -Rekrutierung
Hochschul-Marketing & -Rekrutierung
Metin Aydin
 
2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II
2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II
2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II
professorhood
 
Golf is better
Golf is betterGolf is better
Golf is better
fink2fink2
 

Destaque (19)

Hs303 sadfs@sad..asd:\][
Hs303 sadfs@sad..asd:\][Hs303 sadfs@sad..asd:\][
Hs303 sadfs@sad..asd:\][
 
Experimentalstudie Messung der Schallgeschwindigkeit von Bohrschlämmen unter ...
Experimentalstudie Messung der Schallgeschwindigkeit von Bohrschlämmen unter ...Experimentalstudie Messung der Schallgeschwindigkeit von Bohrschlämmen unter ...
Experimentalstudie Messung der Schallgeschwindigkeit von Bohrschlämmen unter ...
 
Presentación1
Presentación1Presentación1
Presentación1
 
Vestidos de gracia_10
Vestidos de gracia_10Vestidos de gracia_10
Vestidos de gracia_10
 
Perdiz
PerdizPerdiz
Perdiz
 
Grundsätze
GrundsätzeGrundsätze
Grundsätze
 
Warum männer früher sb
Warum männer früher   sbWarum männer früher   sb
Warum männer früher sb
 
Apoyo a acevedo grafica
Apoyo a acevedo graficaApoyo a acevedo grafica
Apoyo a acevedo grafica
 
Hochschul-Marketing & -Rekrutierung
Hochschul-Marketing & -RekrutierungHochschul-Marketing & -Rekrutierung
Hochschul-Marketing & -Rekrutierung
 
Solucion de ensamble
Solucion de ensambleSolucion de ensamble
Solucion de ensamble
 
Newsletter 01 2016
Newsletter 01 2016Newsletter 01 2016
Newsletter 01 2016
 
Das "Geschichtsbureau" 2.0 - Eine Kompetenzwerkstatt am Fachbereich Geschicht...
Das "Geschichtsbureau" 2.0 - Eine Kompetenzwerkstatt am Fachbereich Geschicht...Das "Geschichtsbureau" 2.0 - Eine Kompetenzwerkstatt am Fachbereich Geschicht...
Das "Geschichtsbureau" 2.0 - Eine Kompetenzwerkstatt am Fachbereich Geschicht...
 
Binder1
Binder1Binder1
Binder1
 
Leo el león, el rey de las bestias
Leo el león, el rey de las bestiasLeo el león, el rey de las bestias
Leo el león, el rey de las bestias
 
Metodos paratu leccion
Metodos paratu leccion Metodos paratu leccion
Metodos paratu leccion
 
2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II
2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II
2 > MODALS OF DEDUCTION: EXPOSITION OF GRAMMAR - PART II
 
Top Investment Konferenz 2012
Top Investment Konferenz 2012Top Investment Konferenz 2012
Top Investment Konferenz 2012
 
Golf is better
Golf is betterGolf is better
Golf is better
 
Stand GDF
Stand GDFStand GDF
Stand GDF
 

Semelhante a Sync toasync

1213 Threads [2] Programació concurrent
1213 Threads [2] Programació concurrent1213 Threads [2] Programació concurrent
1213 Threads [2] Programació concurrent
Oriol Torres
 
Sistemes operatius; apunts
Sistemes operatius; apuntsSistemes operatius; apunts
Sistemes operatius; apunts
Melanie Nogué
 
Ubuntu 10.04 LTS en el centres
Ubuntu 10.04 LTS en el centresUbuntu 10.04 LTS en el centres
Ubuntu 10.04 LTS en el centres
Avel·lí
 
Diàleg del projecte
Diàleg del projecteDiàleg del projecte
Diàleg del projecte
SergiTorres23
 

Semelhante a Sync toasync (20)

Aplicacions Interactives multiplataforma_pac3
Aplicacions Interactives multiplataforma_pac3Aplicacions Interactives multiplataforma_pac3
Aplicacions Interactives multiplataforma_pac3
 
Wcf i signalR : Business Feedback
Wcf i signalR : Business FeedbackWcf i signalR : Business Feedback
Wcf i signalR : Business Feedback
 
Programem la placa Arduino - Presentación para la asignatura de robótica
Programem la placa Arduino - Presentación para la asignatura de robóticaProgramem la placa Arduino - Presentación para la asignatura de robótica
Programem la placa Arduino - Presentación para la asignatura de robótica
 
PW_pac1
PW_pac1PW_pac1
PW_pac1
 
1213 Threads [2] Programació concurrent
1213 Threads [2] Programació concurrent1213 Threads [2] Programació concurrent
1213 Threads [2] Programació concurrent
 
Programació Web - PAC 4 - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 4 - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 4 - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 4 - Multimèdia (UOC) - Paquita Ribas
 
Sistemes operatius; apunts
Sistemes operatius; apuntsSistemes operatius; apunts
Sistemes operatius; apunts
 
Glossari-1.pdf
Glossari-1.pdfGlossari-1.pdf
Glossari-1.pdf
 
Programació Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 2 correcció - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
 
Ubuntu 10.04 LTS en el centres
Ubuntu 10.04 LTS en el centresUbuntu 10.04 LTS en el centres
Ubuntu 10.04 LTS en el centres
 
Programació Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 4 correcció - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
 
Turbo Gears, Framework De Python Per Aplicacions Web
Turbo Gears, Framework De Python Per Aplicacions WebTurbo Gears, Framework De Python Per Aplicacions Web
Turbo Gears, Framework De Python Per Aplicacions Web
 
Aplicacions Interactives multiplataforma_pac1
Aplicacions Interactives multiplataforma_pac1Aplicacions Interactives multiplataforma_pac1
Aplicacions Interactives multiplataforma_pac1
 
Presentació Ajax
Presentació AjaxPresentació Ajax
Presentació Ajax
 
UD3 Programació
UD3 ProgramacióUD3 Programació
UD3 Programació
 
Tests nunit nunitforms
Tests nunit nunitformsTests nunit nunitforms
Tests nunit nunitforms
 
Robo Mind
Robo MindRobo Mind
Robo Mind
 
UD3 PROGRAMACIÓ
UD3 PROGRAMACIÓUD3 PROGRAMACIÓ
UD3 PROGRAMACIÓ
 
Hello NFC!
Hello NFC!Hello NFC!
Hello NFC!
 
Diàleg del projecte
Diàleg del projecteDiàleg del projecte
Diàleg del projecte
 

Sync toasync

  • 1. De Síncron a Asíncron El que pretenc en aquest document és mostrar de manera senzilla com passar d'un mètode síncron a un asíncron. Per fer-ho utilitzaré una petita aplicació Winforms amb un formulari que conté un botó i una etiqueta. Simularem que quan premem el botó executa un mètode que conta el número de registres que hi ha en un repositori de dades d'exemple, i el resultat el pinta en l'etiqueta. El que farem és posar el codi del event del botó, primer de manera síncrona, i després de manera asíncrona, utilitzant tècniques diferents, segons el framework de .NET. (El projecte l'adjuntaré al final de tot del document.) Un cop creat el projecte i el formulari, en centrem en el codi principal. Mètode Síncron /// <summary> /// Versió síncrona /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { label1.Text = RepositoryExample.CountExamples().ToString(); } namespace ConvertSyncToAsync { public class RepositoryExample { public static int CountExamples() { System.Threading.
  • 2. Thread.Sleep(5000); return 10000; } } } En el primer requadre tenim el codi que s'executa quan premem el botó. I en el requadre de sota el codi que simula el repositori. Quan executem en aquest context ens trobem que mentre s'executa l'acció, el formulari queda com bloquejat, i no podem fer res amb ell, ni moure'l. Això pot provocar desconcert en l'usuari que la fa servir, i pot pensar que l'aplicació ha deixat de funcionar si dura molt. Mètode Asíncron 1 En versions anteriors al .NET 4.0, per executar mètodes de manera asíncrona podíem fer servir Threads, delegats i en winforms el BackGroundProcess, els quals no recomano, ja que s'ha demostrat que la seva eficiència deixa molt a desitjar. En el exemple que us poso faré servir delegats, ja que d' una manera molt senzilla tenim un resultat molt òptim. /// <summary> /// Versió asíncrona 1. Versions anteriors a .NET 4.0 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Func<int> CountExamples = () => RepositoryExample.CountExamples(); CountExamples.BeginInvoke((result) => { var data = (result.AsyncState as Func<int>).EndInvoke(result); this.Invoke(new Action(() => label1.Text = data.ToString())); }, CountExamples); } Si executem ara amb aquest codi veurem clarament que la interfície respon mentre executa el procés de l´event de butó. Només cal intentar moure-la. Hem de tenir en compte però, que quan executem en threads diferents, des d'un thread no és pot accedir a components de l'altre directament. Els controls del formulari han estat creats per el thread del procés de la interfície, mentre que el delegat s'executa en un altre thread. Si des d'aquet volguéssim accedir a la label directament ens donaria un excepció. Per això cal invocar una acció des del thread principal del UI que contingui el codi que volem executar sobre el component. Mètode Asíncron 2 En la versió 4 del framework, es van introduir les Tasques (Task) com a classes (juntament amb altres del namespace) que ajuden a la programació asíncrona. La veritat es que van molt bé. Solucionen d'una manera molt planera l'execució asíncrona i la sincronització amb el context d'altres fils d'execució, com pot ser el cotext principal des d'on s'inicien el processos de negoci, en el nostre cas el procés del UI. /// <summary> /// Versió asíncrona 2. .NET 4.0. Introducció de les Tasques
  • 3. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { var task = Task<int>.Factory.StartNew(() => RepositoryExample.CountExamples()); task.ContinueWith((result) => label1.Text = result.Result.ToString(), TaskScheduler.FromCurrentSynchronizationContext()); } El resultat és el mateix en tots els casos. Però amb l'aparició de les tasques i tot el que les envolta, fa que la programació asíncrona et sigui més fàcil d'implementar així, que no pas amb threads o delegats. Si no poséssim el paràmetre TaskScheduler.FromCurrentSynchronizationContext() donaria una excepció al intentar accedir des d'un fil a fil de UI per fer l'assignació a la label. Aquest instrucció fa que es sincronitzi el fil al el context de l'UI. Mètode Asíncron 3 Amb la introducció del framework 4.5 han aparegut dues instruccions o declaracions que fan referència explícita a la programació asíncrona. El async i el await. El primer va en la declaració del mètode i indica que aquest és asíncron. El segon precedeix la execució d'un procés, i d'alguna manera li diu que s'executi quan no molesti a ningú. És una aportació molt important al framework (com altres) que cal estudiar molt bé, ja que millora molt els resultats. Van de la maneta de les tasques com podem observar en el codi. /// <summary> /// Versió asíncrona 3. .NET 4.5. Introducció del async i await /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void button1_Click(object sender, EventArgs e) { var result = await RepositoryExample.CountExamplesAsync(); label1.Text = result.ToString(); } namespace ConvertSyncToAsync { public class RepositoryExample { public static int CountExamples() { System.Threading.Thread.Sleep(5000); return 10000; } public static Task<int> CountExamplesAsync() { return Task.Factory.StartNew<int>(() => {
  • 4. System.Threading.Thread.Sleep(5000); return 10000; }); } } } Si ens hi fixem l'event del botó ja el marquem com asíncron. La funció del repositori per poder-la invocar amb un await cal que el tipus de retorn sigui un Task. I un cop dintre l'únic que fem es executar una tasca. En el UI tractem el procés com si fos síncron, el marquem com asíncron async i esperem les operacions internes asíncrones amb el await. Fins aquí la petita introducció. Recomano estudiar molt el tema juntament amb l'execució en paral·lel. No serveix de res tenir més d'un core als ordinadors, si el programes no els fan servir. @SOACAT http://soacat.blogspot.com