Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Sync toasync

299 views

Published on

Describes how to use async pattern i C#

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Sync toasync

  1. 1. De Síncron a AsíncronEl que pretenc en aquest document és mostrar de manera senzilla com passar dun mètode síncron aun 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 deregistres que hi ha en un repositori de dades dexemple, i el resultat el pinta en letiqueta. El quefarem és posar el codi del event del botó, primer de manera síncrona, i després de maneraasíncrona, utilitzant tècniques diferents, segons el framework de .NET.(El projecte ladjuntaré 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. 2. Thread.Sleep(5000); return 10000; } }}En el primer requadre tenim el codi que sexecuta quan premem el botó. I en el requadre de sota elcodi que simula el repositori.Quan executem en aquest context ens trobem que mentre sexecuta lacció, el formulari queda combloquejat, i no podem fer res amb ell, ni mourel. Això pot provocar desconcert en lusuari que la faservir, i pot pensar que laplicació ha deixat de funcionar si dura molt.Mètode Asíncron 1En versions anteriors al .NET 4.0, per executar mètodes de manera asíncrona podíem fer servirThreads, delegats i en winforms el BackGroundProcess, els quals no recomano, ja que shademostrat que la seva eficiència deixa molt a desitjar. En el exemple que us poso faré servirdelegats, 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 elprocés de l´event de butó. Només cal intentar moure-la. Hem de tenir en compte però, que quanexecutem en threads diferents, des dun thread no és pot accedir a components de laltredirectament. Els controls del formulari han estat creats per el thread del procés de la interfície,mentre que el delegat sexecuta en un altre thread. Si des daquet volguéssim accedir a la labeldirectament ens donaria un excepció. Per això cal invocar una acció des del thread principal del UIque contingui el codi que volem executar sobre el component.Mètode Asíncron 2En la versió 4 del framework, es van introduir les Tasques (Task) com a classes (juntament amb altresdel namespace) que ajuden a la programació asíncrona. La veritat es que van molt bé. Solucionenduna manera molt planera lexecució asíncrona i la sincronització amb el context daltres filsdexecució, com pot ser el cotext principal des don sinicien el processos de negoci, en el nostre casel procés del UI./// <summary>/// Versió asíncrona 2. .NET 4.0. Introducció de les Tasques
  3. 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 laparició de les tasques i tot el que les envolta, faque la programació asíncrona et sigui més fàcil dimplementar així, que no pas amb threads odelegats. Si no poséssim el paràmetre TaskScheduler.FromCurrentSynchronizationContext()donaria una excepció al intentar accedir des dun fil a fil de UI per fer lassignació a la label. Aquestinstrucció fa que es sincronitzi el fil al el context de lUI.Mètode Asíncron 3Amb la introducció del framework 4.5 han aparegut dues instruccions o declaracions que fanreferència explícita a la programació asíncrona. El async i el await. El primer va en la declaració delmètode i indica que aquest és asíncron. El segon precedeix la execució dun procés, i dalgunamanera li diu que sexecuti 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 lestasques 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. 4. System.Threading.Thread.Sleep(5000); return 10000; }); } }}Si ens hi fixem levent del botó ja el marquem com asíncron. La funció del repositori per poder-lainvocar amb un await cal que el tipus de retorn sigui un Task. I un cop dintre lúnic que fem esexecutar una tasca. En el UI tractem el procés com si fos síncron, el marquem com asíncron async iesperem les operacions internes asíncrones amb el await.Fins aquí la petita introducció. Recomano estudiar molt el tema juntament amb lexecució enparal·lel. No serveix de res tenir més dun core als ordinadors, si el programes no els fan servir. @SOACAT http://soacat.blogspot.com

×