Category Archives: C#

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.

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 4 – Microsoftova regionalna konferencija


Badge-ENG-04

Po četvrti put, četvrtu godinu za redom, Microsoft BiH organizira regionalnu konferenciju MSnetwork. Mada najmlađa u regionu vrlo brzo je postala prepoznatljiva, kako po kvaliteti predavanja koje konferencija ponudi, tako i sadržajima oko konferencije. Prošlogodišnja konferencija, zaista je ispunila svačija očekivanja, a posebno je hvaljena lokacija gdje se konferencija održavala. Slijedeći dobar feedback, organizator je i ovogodišnju konferenciju zakazao na istom mjestu, a to je hotelski kompleks  Banja Vrućica u okolini Teslića.

Ovogodišnja konferencija će, za razliku od prošlogodišnje, ponuditi još više predavanja, još više predavača. Za razliku od prošlogodinje na kojoj je bilo 3 konferencijska smijera, ove godine organizator je pripremio  6 konferencijskih smjerova i to: DEV, ITPRO, MSC, CS, EDU i BIZ. Manje poznati CS smijer označava Case Study (studija slučaja).Ove godine oko 80 predavača održat će predavanja na konferenciji.

Kao i prošle godine već je urađena Windows Phone applikacija koja daje sve informacije vezane za konferenciju koju možete skinuti sa ovog linka u koliko posjedujete WP telefon. Ove godine urađena je i Windows Store aplikacija za MSNetwork koju također možete skinuti sa ovog link u koliko posjedujete Windows 8 OS. Za WP i WS aplikaciju se pobrinuo naš MVP Spaso.

I na kraju, s vrlo radosnom viješću obavještavam javnost da sam jedan od predavača na konferenciji, gdje ću govoriti oko asinhronog programiranja te kako ovu modernu tehniku programiranja najbolje implementairati u aplikacijama. Predavanje će obilovati demo primjerima sa originalnom tematikom. Više informacija oko predavanje možete dobiti na oficijelnom linku.

Vidimo se na konferenciji.

How to run the code daily at specific time in C#


When you want to make some delay in running code you can use Task.Delay(TimeSpan interval) method . This method is similar to Thread.Sleep, but it is nicer. The argument of the method represent TimeSpan type. For example if you want to wait 5 second you can call the following code:

Task.Delay(TimeSpan.FromSeconds(5));

Or you want to wait 2 hours:

Task.Delay(TimeSpan.FromHourss(2));

You can easily use Task.Delay to run some code at certain time. For example you want to run some method every day at 1:00:00 AM. To implement this example you can use Task.Delay method on the following way:
First Convert the time in to DateTime type. Make diference between now and the time you want to run the code. Call Delay method with TimeSpan of previous time interval. The following code solve this problem:

class Program
    {
        static void Main(string[] args)
        {
            //Time when method needs to be called
            var DailyTime = "01:00:00";
            var timeParts = DailyTime.Split(new char[1] { ':' });

            var dateNow = DateTime.Now;
            var date = new DateTime(dateNow.Year, dateNow.Month, dateNow.Day,
                       int.Parse(timeParts[0]), int.Parse(timeParts[1]), int.Parse(timeParts[2]));
            TimeSpan ts;
            if (date > dateNow)
                ts = date - dateNow;
            else
            {
                date = date.AddDays(1);
                ts = date - dateNow;
            }

            //waits certan time and run the code
            Task.Delay(ts).ContinueWith((x)=> SomeMethod());

            Console.Read();
        }

        static void SomeMethod()
        {
            Console.WriteLine("Method is called.");
        }
    }

If you want that code to run every day, just put it in while loop.

Happy programming.

Follow

Get every new post delivered to your Inbox.

Join 494 other followers