Using TaskCompletionSource in wraping event handler


Using TaskCompletionSource you can wrap any operation in to task, so that you can do anything you can with the task object. The TaskCompletionSource class is very important and today’s post will be explain how to wrap button click event in to TaskCompletionSource. With this wrap we will see how complicated operation behind click button handler can be simplified.

The for this blog post is simple Windows Store app shown on the picture below.

screen_sample2

When the Play Slides is clicked, Image slide is started which start animation of images. XAML code behind this app is listed here:

<Page.Resources>
    <Storyboard x:Name="animImageSlideIn">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
                                        Storyboard.TargetName="img">
            <EasingDoubleKeyFrame KeyTime="0" Value="900"/>
            <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0" />
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Height="250" >
        <Button x:Name="playbtn" Height="50" Margin="0,5,0,5" Content="Play Slides" HorizontalAlignment="Center" Click="playbtn_Click"></Button>

        <Image x:Name="img" HorizontalAlignment="Center">
            <Image.RenderTransform>
                <CompositeTransform TranslateY="900" />
            </Image.RenderTransform>
        </Image>
    </StackPanel>
</Grid>

First, it will be presented  the implementation without TaskCompletionSource. The Play Slides Click event is the following code:

private async void  playbtn_Click(object sender, RoutedEventArgs e)
{
    int i = 1;

    EventHandler<object> handler = null;

    handler = delegate
    {
        if (i <= 3)
        {
            playbtn.Content = string.Format("Slide Image {0}",i);

            LoadSourceImage(i);

            animImageSlideIn.Begin();

            i++;
        }
        else
        {
            playbtn.Content = "Play Slides";
            animImageSlideIn.Completed -= handler;
            LoadSourceImage(0);

        }
    };

    animImageSlideIn.Completed += handler;
    handler(null,null);
}

As we can see from the listing above the code is pretty much long and little bit confused because we subscribe to the handler and call it as much as we reach the magic number of slides. Whe the number of slides is reached we unsubscribed from the handler and exit  the method.

Now implement the same functionality with the TaskCompletionSource class. The following listing shows the implementation:

private async void playbtn_Click(object sender, RoutedEventArgs e)
{

for(int i=1; i<=3; i++)
{
playbtn.Content = string.Format("Slide Image {0}",i);
LoadSourceImage(i);
await animImageSlideIn.RunAsync();
}

playbtn.Content = "Play Slides";
}

As we can see the implementation is very simple and concise. in for loop we call LoadSourceImage then asynchrony run animation.

The source code of the demo can be found by clicking the image below:

This blog post is inspired by Stephen Toub //build/ session.

Advertisement

Pausing and cancelling async method in C#


Responsiveness of your app is not just fee UI thread by implementing async. It is more that that. When a long operation is under process in your app, user sometimes wants to cancel it  or  pause the operation. Imagine your app processing hundreds of files or images. Such a operation can take more that few seconds and user must have option to cancel it. Canceling and pausing are very important feature for every app that implements long operations.

This blog post will present the way of using CancelationToken built in cancel feature in .NET, as well as a PauseToken custom implementation which is very similar to CancelationToken.

Original implementation of PauseToken is from the pfxteam blog which you can find here.

We will implement simple Windows Store app with cancel and pausing the async operation. The picture below shows the sample app:

screen_sample1

 

As you can see when the Start Process button is clicked it begins process of processing image files. There is also ProgressRing control which shows the progress and percentage of completeness. From the right side you can see two buttons. The Cancel button cancels the operation, and pause button pauses operation until the Pause button is clicked again.

The implementation behind Process button is the folowing:

private async  void btnProcess_Click(object sender, RoutedEventArgs e)
{
    //creating cancel and pause token sources
    m_pauseTokeSource = new PauseTokenSource();
    m_cancelationTokenSource = new CancellationTokenSource();

    //get al picture from picture library
    var picturesFolder = KnownFolders.PicturesLibrary;
    var fileList = await picturesFolder.GetFilesAsync();

    //set ProgressRing to active
    ring2.IsActive = true;

    try
    {
        //asynchrony process files, by passing pasue and calcel tokens

        await ProcessImages(fileList, m_pauseTokeSource.Token, m_cancelationTokenSource.Token);
    }
    catch (Exception)
    {
        //do nothing when somthing went wrong not when taks is canceled
    }
    finally
    {
        //make inactive ProgressRing
        ring2.IsActive = false;
    }
}

Click event implementation of the Start Process button 

First we create Cancel and Pause Source tokens. Gent the picture content in form of list of files. Then we call asynchonious ProcessImages method by passing list of images files, cancel and pause tokens. Process images is called within try catch finally blocks, because every cancel task throws exception.

Implementation ProcessImages async method

ProcesImage method is async method which accept cancelation and pasue token nad returns Task object.

public async Task ProcessImages(IEnumerable<StorageFile> images, PauseToken pauseToken, CancellationToken cancelToken)
{
    double count=images.Count();
    double current=0;
    foreach (var file in images)
    {
        //if the paise is active the code will wait here but not block UI thread
        await pauseToken.WaitWhilePausedAsync();

        ring2Text.Text = string.Format("{0}%",(int)(100*current / count));

        await ProcessAsync(file, cancelToken);
        current++;
    }
    ring2Text.Text = string.Format("100%");
}

In foreach loop first we await pauseToken.WaitWhilePausedAsync(); which wait if IsPause property of the Token class is true, otherwize there is no awaiting here. The next await is out Delay which takes cancelation token as parameters. When the Pause button is clicked, pauseToken is awaiting until the pause button is clicked again. In case of cancelation when the Cancel button is clicked the Cancel() method of the cancelationTokenSource is called and exception is thorwn. Then processImages method is interupted and finally blick progressring is disabled.
Pause and Cancel Click implementation are shown in the following listing:

private void btnPause_Click(object sender, RoutedEventArgs e)
{
 m_pauseTokeSource.IsPaused = !m_pauseTokeSource.IsPaused;
}

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
 m_cancelationTokenSource.Cancel();
}

Complete source code can be downloaded from link below.

MSNetwork 3: Paralelno i asinhrono programirnje primjeri i prezentacijska datoteka


msnetwork

U ovom postu pobrojani su svi demo primjeri  sa kratkim objašnjenjem koje sam na MSNetwrok 3 predavanju demonstrirao. Ovo ujedno i predstavlja moje aktivnosti zadnjih nekoliko godina vezanih oko ove teme.

Tačno prije 5 godina odnosno u aprilu 2008 godine (22. aprila 2008.) napisao sam prvi članak oko paralelnog programiranja, dok je 5 mjeseci ranije te godine izbačena prva CTP verzija ParallelFx biblioteke.

Ovim MSNetwork predavanjem želio sam ujedno i da sve to objedinim i da široj javnosti prenesem iskustva iz ovog područja programiranja. Ovaj blog post sadrži izvorni kod za sve demo primjere koji su planirani za ovo predavanje. Moguće je, (jer blog post pišem ranije) da neki od primjera nije demonstriran zbog vremena, pa ovom prilikom ih objavljujem sviju sa kratkim pojašnjenjem.

Ukupno za ovo predavanje planirano je 9 demo primjera i to:

1. Power point prezentacija predavanja.

2. Demo primjeri sa predavanja

Primjer manipulacije sa objektom Thread, i kako manipulisati u višenitnom okruženju.
Primjer manipulacije sa Task objektom, kao osnovnim konceptom pralelnog i asinhronog programiranja.
Demo sadrzi 5 različitih primjera korištenja for, foeach, parallelLoopState i primjer koordinacije i razmjene podataka izmedju niti.
PLINQ primjer koristenja paraleliziranih LINQ upita.
Primjer korištenja Partisionera, kojim dijelimo poslove na više taskova.
Primjer koji demonstrira Race Condition fenomen kada dvije niti u isto vrijeme pokusavaju da promjene vrijednost varijable.
Realni primjer primjene ParallelFx u rjesavanju sistema linearnih jednačina sa 1000 nepoznatih.
Primjer asinhronog programiranja na strani klijenta. Kako stari sekvencijalni kod pretvoriti u asinhroni.
Primjer asinhronog programiranja na strani servera. Korištenje asinhronog programiranja u optimizaciji ASP.NET aplikacija i mogućnosti povećavanja performansi i odziva aplikacija.

MSNetwork 3. po redu Microsoft konferencija u BiH


msnetwork

Banja Vrućica 3. i 4. aprila 2013 g.

Sada već tradicionalno po treći put se održava Bosanskohercegovačka Microsoft konferencija:  MSNetwork 3. Mjesto održavanja ovaj put je Banja Vrućica zdravstveno turistički centar koji se nalazi u blizini Teslica, gradića na putu izmedju Banjaluke i Doboja.

Kao i prvi put kad se održavala u Banjaluci prije 3 godine, i ovaj put konferencija će ponuditi najbolje teme, predavače i cijelu konferenciju učiniti nezaboravnom bas onako kako je to bilo i ranije. Naravno, svaki put ljudi iz Microsofta BiH se potrude da ona bude bolja od prethodne pa i ovaj put ne sumnjam u to. Ovaj put rekordan broj predavača kao i predavanja. Prva konferencija je krenula sa 3 tracka, da bi prošle godine bio i MSC track na kojem predavanja daju ljudi iz MS Communitya, da bi ove godine bio i EDU track, posvećen nekim stručnim  temama.

Na ovoj konferenciji se se naći zaista za svakog ponešto. Gotovo svi poznati  predavači iz Makedonije, Srbije, BiH, Hrvatske i Slovenije, posebno predavači iz Njemačke i drugih evropskih zemalja,  naći će se 3 i 4 aprila u Banja Vrućici. Ukupno 60 predavača govorit će na konferencij što konferenciji čini vrlo atraktivnom, kvalitetnom i zanimljivom.

Koristim ovu priliku da na MSNetwork najavim svoje predavanje. Predavati na MSNetwork konferenciji zaista me čini sretnim i zahvaljujem se organizatorima što su ovo predavanje  uključili u zvanični dio konferencije.

Naziv predavanja, level i kratki opis pročitajte u narednom tekstu.

Paralelno i asinhrono programiranje – izazov za svakog programera (4.april. 2013, 11:30 dvorana Bosna)

par_asyn_conc

Level: 300

Opis predavanja:

Multi-core procesori su realnost, proizvođači ih danas ugrađuju i u grafičke kartice, mobilne telefone pa čak i u veš-mašine. Direktna posljedica razvoja multi-core procesora je prestanak razvoja single-core procesora čiji takt već odavno stoji na magičnoj brojci oko 3 GHz. Kako proizvođači ovom tehnologijom ne mogu povećati takt počeli sa proizvodnjom multi-core procesora, ili višejezgrenih procesora u jednom hardverskom dijelu, što je dalo dodatni vjetar u leđa razvoju procesora. Danas se kućni računari kupuju sa 4 ili 8 jezgri, serveri i do 128 jezgri. Realno se pitanje postavlja: da li softver koji je razvijan nekoliko godina unazad odgovara takvom hardveru? Da li hardver na multi-core procesorima ima smisla vrtiti dosadašnja softverska rješenja? Moguće se upitati i to da li energija koju troši ovakav hardver odgovara korištenju softvera? Imate više od 1 procesora na PC-u, ali ne primjećujete da vaš softver radi brže? Još uvijek koristite klasu Thread ili BackgroundWorker ili Callback funkciju kako bi korisnika zavaravali dok se vaši podaci učitavaju u pozadini? Željeli bi programirati višenitne aplikacije, a da ne formirate niti? Ovo su samo neka od pitanja, čije odgovore daje paralelno i asinhrono programiranje u .NETu. Paralelno i asinhrono programiranje predstavlja novu paradigmu i izazove za moderne programere koji žele iskorištavati sve resurse PC-a, a ne samo jednu jezgru, koji žele programirati višenitno, a da ne formiraju niti, koji žele koristiti nova proširenja koja su sastavni dijelovi .NET 4.5 i C# 5.0.

Pored zvaničnog opisa ovdje bih dodao da će ovo predavanje obilovati realnim primjerima:

1. primjer paralelizacije riješavanje sistema linearnih jednačina sa više od 1000 nepoznatih.

2. primjer asinhronog procesuiranja zahtjeva na ASP.NET  web stranici.

3. procedura konverzije sekvencijalnog koda u asinhroni, praktična iskustva.

4. nekoliko jednostavnih primjera demonstracije Data Race, Thread-Safety, PLINQ,ThreadLocalState i sl.

Nadam se da će predavanje biti zanimljivo, a pogotovu za one koji žele više posmatrati Visual Studio od PowerPointa.

Vidimo se na konferenciji.