Friday, 14 April 2017

AsyncStateMachine in .NET

This article will present a custom AsyncStateMachine that shows how it is possible to create as async awaitable state machine manually. Let's first consider an easy async-await example and implement it using a custom async state machine instead of the default one in .NET. The purpose is to glance more into the inner workings of async. The following code is what is going to be implemented.

   class Program
    {
        static void Main(string[] args)
        {
            try
            {
                CallFooAsync();
            }
            catch (AggregateException ae)
            {
                Console.WriteLine(string.Join(",",
                    ae.InnerExceptions.ToList().Select(e => e.Message).ToArray()));
            }

            Console.WriteLine("Hit any key to continue..");
            Console.ReadKey();
        }

        public static async void CallFooAsync()
        {
            int foo = await FooAsync();
            Console.WriteLine(foo);
        }

        static async Task<int> FooAsync()
        {
            await Task.Delay(5000);
            return 42;
        }


The Main method of the console application is not allowed to have async modifier, so it was necessary to introduce an extra method here. Next off, here is an example of an AsyncStateMachine at its simplest form. It is implemented as a struct.

        struct FooAsyncStateMachine : IAsyncStateMachine
        {

            private int state; 

            public AsyncTaskMethodBuilder<int> methodBuilder;
            private TaskAwaiter awaiter;

            public void MoveNext()
            {
                //State machine
                try
                {
                    if (state == 0)
                    {
                        awaiter = Task.Delay(millisecondsDelay: 5000).GetAwaiter();
                        if (awaiter.IsCompleted)
                        {
                            state = 1;
                            goto state1;
                        }
                        else
                        {
                            state = 1;
                            methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
                        }
                        return;
                    }

                    state1:
                    if (state == 1)
                    {                     
                        methodBuilder.SetResult(42);
                        return;
                    }
                }
                catch (Exception ex)
                {
                    methodBuilder.SetException(ex);
                    return;
                }
            }

            public void SetStateMachine(IAsyncStateMachine stateMachine)
            {
                methodBuilder.SetStateMachine(stateMachine);
            }

        }

The IAsyncStateMachine interface has a method called void MoveNext(). This method is called when the async method starts up. This method can be called multiple times. It contains a state variable to control which step is next. The AsyncMethodBuilder is used to control the result returned from the async method. The method SetResult sets the result returned and the method SetException inside a catch sets an exception, if encountered. Thet method SetStateMachine sets the statemachine struct as the state machine struct itself and is also part of the IAsyncStateMachine. Now that the AsyncStateMachine is defined, it is time to kick it off.

 static Task FooAsync2()
        {
            var stateMachine = new FooAsyncStateMachine();
            stateMachine.methodBuilder = AsyncTaskMethodBuilder<int>.Create();
            stateMachine.methodBuilder.Start(ref stateMachine);
            return stateMachine.methodBuilder.Task;
        }

The AsyncMethodBuilder inside the IAsyncStateMachine is using the Create method and Start method and returns a Task. In this article the async state machine is hard coded and not made general. Of course in .NET the AsyncStateMachine used is far more complex. But creating an async state machine yourself is a nice introduction to taking a deeper look into what async really is. Async-await is rewriting your code and could have been implemented in earlier versions of .NET. Async-await not changes the functionality of your code, but the way it is executed. It provides a way to halt a method and free up the thread, for example the UI thread and run code in the background, then continue later on again. It also allow parallel code.

Resources:

Saturday, 3 December 2016

Parallell execution with threads in C# - Old Stars finder

This article will present parallell execution of threads in C# to find old stars in a star formation known as W5 in the constellation of Cassiopeia with the Spitzer Space telescope. The code is from the book "C# Multithreaded and Parallell programming" by Packt Publishing by author Rodney Ringler et. al.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Drawing.Imaging;


namespace OldStarsFinder
{
    public partial class Form1 : Form
    {

        //The number of processors or cores available in the computer for this application
        private int priProcessorCount = Environment.ProcessorCount;
        //The bitmaps list
        private List<Bitmap> prloBitmapList;
        //The long list with the old stars count 
        private List<long> prliOldStarsCount;
        //The threads list
        private List<Thread> prloThreadList;
        //The original huge infrared bitmap portrait
        Bitmap proOriginalBitmap; 

        public Form1()
        {
            InitializeComponent();
        }

        public bool IsOldStar(Color poPixelColor)
        {
            //Hue between 150 and 258
            //Saturation more than 0.10 
            //Brightness more than 0.90
            return ((poPixelColor.GetHue() >= 150 && (poPixelColor.GetHue() <= 258)) &&
                (poPixelColor.GetSaturation() >= 0.10) &&
                (poPixelColor.GetBrightness() >= 0.90)); 
        }

        private Bitmap CropBitmap(Bitmap proBitmap, Rectangle proRectangle)
        {
            //Create a new bitmap copying the portion of the original defined by proRectangle and keeping the PixelFormat 
            var loCroppedBitmap = proBitmap.Clone(proRectangle, proBitmap.PixelFormat);
            //Return the cropped bitmap 
            return loCroppedBitmap;
        }

        private void ThreadOldStarsFinder(object poThreadParameter)
        {
            //Retrieve the thread number reeived in object poThreadParameter 
            int liThreadNumber = (int) poThreadParameter;
            //The pixel matrix (bitmap) row number (Y)
            int liRow;
            //The pixel matrix (bitmap col number (X)
            int liCol;
            //The pixel color 
            Color loPixelColor;
            //Get my bitmap part from the bitmap list 
            Bitmap loBitmap = prloBitmapList[liThreadNumber];

            //Reset my old stars counter 
            prliOldStarsCount[liThreadNumber] = 0;
            //Iterate through each pixel matrix (bitmap) row 
            for (liRow = 0; liRow < loBitmap.Height; liRow++)
            {
                //Iterate through each pixel matrix (bitmap) cols 
                for(liCol = 0; liCol < loBitmap.Width; liCol++)
                {
                    //Get the pixel color for liCol and liRow 
                    loPixelColor = loBitmap.GetPixel(liCol, liRow);
                    //Get the pixel color for liCol and liRow 
                    if (IsOldStar(loPixelColor))
                    {
                        //The color range correspons to an old star
                        //Change its color to a pure blue 
                        loBitmap.SetPixel(liCol, liRow, Color.Blue);
                        //Increase the old stars counter 
                        prliOldStarsCount[liThreadNumber]++;
                    }
                    else
                    {
                        loBitmap.SetPixel(liCol, liRow, Color.FromArgb(128, loPixelColor));
                    }
                }
            }
            //Simulate heavy processing
            Random rnd = new Random();
            Thread.Sleep(rnd.Next(2000, 2500)); 
        }

        private void WaitForThreadsToDie()
        {
            //A bool flag 
            bool lbContinue = true;
            int liDeadThreads = 0;
            int liThreadNumber;
            while (lbContinue)
            {
                for(liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
                {
                    if (prloThreadList[liThreadNumber].IsAlive)
                    {
                        //One of the threads is still alive
                        //exit the for loop and sleep 100 milliseconds 
                        break;
                    }
                    else
                    {
                        //Increase the dead threads count 
                        liDeadThreads++;

                        progressBar1.Value = (int) ((liDeadThreads * 1.0 / priProcessorCount * 1.0) * 100.0);
                    }
                }

                if (liDeadThreads == priProcessorCount)
                {
                    //All the threads are dead, exit the while loop 
                    break; 
                }
                Thread.Sleep(100);
                liDeadThreads = 0; 
            }
        }

        private void ShowBitmapWithOldStars()
        {
            int liThreadNumber;
            //Each bitmap portion 
            Bitmap loBitmap;
            //The starting row in each iteration 
            int liStartRow = 0;

            //Calculate each bitmap's height 
            int liEachBitmapHeight = ((int) (proOriginalBitmap.Height / priProcessorCount)) + 1;

            //Create a new bitmap with the whole width and height 
            loBitmap = new Bitmap(proOriginalBitmap.Width, proOriginalBitmap.Height);
            Graphics g = Graphics.FromImage((Image) loBitmap);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            for (liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
            {
                //Draw each portion in its corresponding absolute starting row 
                g.DrawImage(prloBitmapList[liThreadNumber], 0, liStartRow);
                //Increase the starting row 
                liStartRow += liEachBitmapHeight;        
            }

            //Show the bitmap in the PictureBox picStarsBitmap 
            picStarsBitmap.Image = loBitmap;

            g.Dispose(); 
        }

        private void butFindOldStars_Click(object sender, EventArgs e)
        {
            progressBar1.Visible = true;

            proOriginalBitmap = new Bitmap(pictureBox1.Image);

            //Thread number 
            int liThreadNumber;
            //Create the thread list, the long list and the bitmap list 
            prloThreadList = new List<Thread>(priProcessorCount);
            prliOldStarsCount = new List<long>(priProcessorCount);
            prloBitmapList = new List<Bitmap>(priProcessorCount);

            int liStartRow = 0;

            int liEachBitmapHeight = ((int) (proOriginalBitmap.Height / priProcessorCount)) + 1;

            int liHeightToAdd = proOriginalBitmap.Height;
            Bitmap loBitmap; 

            //Initialize the threads 

            for (liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
            {
                //Just to occupy the number 
                prliOldStarsCount.Add(0); 

                if (liEachBitmapHeight > liHeightToAdd)
                {
                    //The last bitmap height perhaps is less than the other bitmap height
                    liEachBitmapHeight = liHeightToAdd; 
                }

                loBitmap = CropBitmap(proOriginalBitmap, new Rectangle(0, liStartRow, proOriginalBitmap.Width, liEachBitmapHeight));
                liHeightToAdd -= liEachBitmapHeight;
                liStartRow += liEachBitmapHeight;
                prloBitmapList.Add(loBitmap);

  

                //Add the new thread, with a parameterized start (to allow parameters)
                prloThreadList.Add(new Thread(new ParameterizedThreadStart(ThreadOldStarsFinder))); 
            }

            //Now, start the threads
            for (liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
            {
                prloThreadList[liThreadNumber].Start(liThreadNumber); 
            }

            WaitForThreadsToDie();

            ShowBitmapWithOldStars();

            progressBar1.Visible = false;
        }

    }
}

The code is available as a Windows Forms application in a Visual 2015 Solution available for download (zip) below:
Old Stars Finder (.zip) W5 image (NASA website): W5 image

Sunday, 27 November 2016

Making a simple accordion in Bootstrap 3


Creating an accordion for a web site is a breeze with Bootstrap 3. Just including the Bootstrap CSS and Javascript files and jQuery, we can start building an accordion. The accordion is a menu that shows one menu item a time. These menu items are panels and an accordion resembles a tab control with tabs, but is vertically stacked default. The following HTML page renders a simple accordion with Boostrap, CSS, Javascript and HTML.

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">

  <div id="accordion" class="panel-group">
  
   <div class="panel panel-success">
    <div class="panel-heading">
     <h4 class="panel-title"><a href="#collapse1" data-toggle="collapse" data-parent="#accordion">Collapsible panel 1</a></h4>
    </div>
    <div id="collapse1" class="panel-collapse collapse">
     <div class="panel-body"><div class="well">This is a nice collapsible panel.</div><p>This is a test.</p></div>
     <div class="panel-footer">Panel footer</div>
    </div>   
   </div>
   
    <div class="panel panel-warning">
    <div class="panel-heading">
     <h4 class="panel-title"><a href="#collapse2" data-toggle="collapse" data-parent="#accordion">Collapsible panel 2</a></h4>
    </div>
    <div id="collapse2" class="panel-collapse collapse">
     <div class="panel-body">This is another nice panel</div>
     <div class="panel-footer">Hey a panel footer too!</div>
    </div>   
   </div>
   
    <div class="panel panel-default">
    <div class="panel-heading">
     <h4 class="panel-title"><a href="#collapse3" data-toggle="collapse" data-parent="#accordion">Collapsible panel 3</a></h4>
    </div>
    <div id="collapse3" class="panel-collapse collapse">
     <div class="panel-body">Omg a third panel!</div>
     <div class="panel-footer">Let's have another Panel footer too!</div>
    </div>   
   </div>
  
  </div>  
  
</div>

</body>
</html>

Make note that we here use the data-parent HTML5 extension to point to the parent element to get the accordion effect of only showing one panel at a time. Each panel consists of a panel with a panel heading, having a panel title and then a panel body and finally a panel footer. We use the CSS framework of Bootstrap to achieve this.