Saturday, June 10, 2017

Async and Await - Asynchronous Programming


Microsoft introduced Async and Await keyword with .Net framework 4.5. Async and Await keyword can be used to improve your application’s overall responsiveness by using asynchronous programming. Asynchronous programming is essential when your application is doing some activity which makes UI unresponsive. You can move that activity to execute asynchronously so it doesn’t block UI and your application will be responsive.

You should consider using Async and Await when you want to keep your application responsive. Async method provides easier way to do long running work in background without blocking thread. Ideally method is decorated with Async keyword should contain one await statement. If you don’t write await statement in Async method, it won’t give compile error but execute as synchronous method.

Below are few things to remember about Async and Await method.

  • The method should contain async modifier.
  • Async method return type should be
    • Task
    • Task<T>
    • Void
  • The method usually includes at least one await expression.

Let’s have a look on below example.

Code –

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    public async void DoSum(int number)
    {
        Console.WriteLine("Task started");
        var result = Calculate(number);
        Console.WriteLine("Task completed");
        if (!result.IsCompleted)
            await result;
        Answer.Text = result.Result.ToString();
        Console.WriteLine(string.Format("Answer is {0}", result.Result.ToString()));
    }
    public async Task<int> Calculate(int number)
    {
        var sum = 0;
        Task myTask = new Task(() =>
        {
            for (int i = 1; i <= number; i++)
            {
                System.Threading.Thread.Sleep(1000);
                sum += i;
            }
        });
        myTask.Start();
        await myTask;
        return sum;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (!string.IsNullOrEmpty(Input.Text))
        {
            Console.WriteLine("Sum process started");
            var number = Convert.ToInt32(Input.Text);
            DoSum(number);
            Console.WriteLine("Sum process completed");
        }
    }
}

Output –

Sum process started
Task started
Task completed
Sum process completed
Answer is 55



As you can see in output, the UI doesn’t block and cursor immediately return to UI. The sum is calculated and updated asynchronously after all execution completed.

Now let’s make little change to this programme and use Task.Wait() method to complete task instead of await. I added myTask.wait() instead of await myTask.

public async Task<int> Calculate(int number)
{
    var sum = 0;
    Task myTask = new Task(() =>
    {
        for (int i = 1; i <= number; i++)
        {
            System.Threading.Thread.Sleep(1000);
            sum += i;
        }
    });
    myTask.Start();
    myTask.Wait();
    return sum;
}

Output –

Sum process started
Task started
Task completed
Answer is 55
Sum process completed

As you can see in output, till the sum is calculated UI is blocked and after that sum process is completed. That means myTask.wait() blocks the thread until task completed.

Difference between await and task.wait() - 

Task.wait blocks the thread and await doesn’t block thread and UI.

I hope this article helps you to know more about async and await. Please leave your feedback in comments below.

You can download full code from Gist.

See also –


Sunday, May 28, 2017

Command Pattern

Command design pattern can be used while designing Menu Items, Tool Bar, Status Bar etc functionalities in application. This pattern can also be useful to provide Undo/Redo like functionalities in application. Command Pattern falls under behavioral pattern of GOF (Gang of Four) pattern.

When to use –


Command Pattern encapsulates request under an object and pass it to the invoker object. The invoker object will pass it to proper command object which will execute the command. This pattern commonly used in UI Buttons, Menu, Tool Bar, Status Bar, Progress Bar etc in many applications. This pattern can also be used to provide multiple level Undo/Redo functionalities for applications.  

Major components of command pattern –


Command – This is an interface which specifies execute action.
Concrete Command – This is concrete class which provides implementation for execute operation.
Client – This class creates and executes commands.
Invoker – This class will ask the command to execute their actions.
Receiver – This class knows how to perform action attached with request.

See below example of Command pattern.

Code –
//Command interface
public interface ICommand
{
    void Execute();
    string Name { get; }
}
//Concrete Command class
public class BuyCommand : ICommand
{
    private Product Product;
    public string Name
    {
        get
        {
            return "Buy Command";
        }
    }
    public BuyCommand(Product product)
    {
        Product = product;
    }
    public void Execute()
    {
        Console.WriteLine("Executing {0}", Name);
        Product.Buy();
    }
}
//Concrete Command class
public class SellCommand : ICommand
{
    private Product Product;
    public string Name
    {
        get
        {
            return "Sell Command";
        }
    }
    public SellCommand(Product product)
    {
        Product = product;
    }
    public void Execute()
    {
        Console.WriteLine("Executing {0}", Name);
        Product.Sell();
    }
}
//Receiver class
public class Product
{
    public int Quantity { get; set; }
    public string Name { get; set; }
    public Product(string prodName, int qty)
    {
        Name = prodName;
        Quantity = qty;
    }
    public void Buy()
    {
        Console.WriteLine("Purchased {0} quantities of {1}", Quantity, Name);
    }
    public void Sell()
    {
        Console.WriteLine("Sold {0} quantities of {1}", Quantity, Name);
    }
}
//Invoker class
public class Portal
{
    public string PortalName { get; set; }
    public Portal(string name)
    {
        PortalName = name;
    }
    public List<ICommand> orderList = new List<ICommand>();
    public void AddOrder(ICommand cmd)
    {
        orderList.Add(cmd);
    }
    public void ExecuteOrder()
    {
        Console.WriteLine("Executing all orders from {0}", PortalName);
        foreach(var order in orderList)
        {
            order.Execute();
        }
    }
}
//Client class
class Program
{
    static void Main(string[] args)
    {
        Product laptop = new Product("Laptop", 2);
        BuyCommand buyLaptop = new BuyCommand(laptop);
        SellCommand sellLaptop = new SellCommand(laptop);

        Portal portal = new Portal("Amazon.in");
        portal.AddOrder(buyLaptop);
        portal.AddOrder(sellLaptop);

        portal.ExecuteOrder();

        Console.ReadLine();
    }
}

Output –




As you can see in this example, user can create receiver object and also create objects for multiple commands. In this example Product is Receiver class and Portal is invoker class. The portal object will invoke BuyCommand and SellCommand as per their order. This example can also be extended to add Undo/Redo functionality via using Stack and modifying invoker class.

You can download full code from Gist.

I hope this article helps you to know more about Command Design Pattern. Please leave your feedback in comments section below.

References –

See Also –


Sunday, April 30, 2017

Parallel.Invoke – Task Parallel Library


In my previous article, I explained about Parallel.For and Parallel.Foreach Loop in detail. In this article I will explain, how to use Parallel.Invoke to do multiple tasks concurrently.

Parallel.For and Parallel.Foreach can be used to loop asynchronously, but Parallel.Invoke can be used to do multiple tasks concurrently. Parallel.Invoke method is part of System.Threading.Tasks and accept array of action delegates as input and run all action delegates in parallel.

You can use Parallel.Invoke method when you want to do multiple tasks in parallel. This will be always faster than calling all the tasks synchronously. Task parallel library internally manages to divide and run multiple task in different threads in parallel. It also manages thread scheduling and scaling automatically as per the number of cores on your computer. There is no guarantee in which order all your tasks are executed and completed. See below example.

Code –

namespace ParallelInvoke
{
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main(string[] args)
    {
        Parallel.Invoke(() =>
        {
            Console.WriteLine("Starting first task");
            Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
            DoFirstTask();
        }, () =>
        {
            Console.WriteLine("Starting second task");
            Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
            DoSecondTask();
        }, () =>
        {
            Console.WriteLine("Starting third task");
            Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
            DoThirdTask();
        }
            );
        Console.ReadLine();
    }
    public static void DoFirstTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Total numbers - {0}", numbers.Count());
        Console.WriteLine("First task completed.");
    }
    public static void DoSecondTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Sum of all numbers - {0}", numbers.Sum());
        Console.WriteLine("Second task completed.");
    }
    public static void DoThirdTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Average of all numbers - {0}", numbers.Average());
        Console.WriteLine("Third task completed.");
    }
}
}

Output –


As you can see in above example, there are three delegates assigned to Parallel.Invoke method to execute. As i mentioned earlier that all delegates runs in different threads concurrently hence the order of task execution is different. You can also check managed thread id for each task on which they are executing.

Cancelling Parallel.Invoke method –


You can cancel any task which is running via Parallel.Invoke method based on certain condition. Parallel.Invoke method has overload which accepts ParallelOptions in which you can specify cancellation token. See Parallel.Invoke overload method which accept ParallelOptions as parameter.

public static void Invoke(ParallelOptions parallelOptions, params Action[] actions);

See below little bit of modified code to accept cancel request.

Code –
namespace ParallelInvoke
{
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static CancellationTokenSource cancelToken = new CancellationTokenSource();
    static void Main(string[] args)
    {
        ParallelOptions options = new ParallelOptions();
        options.CancellationToken = cancelToken.Token;
        try
        {
            Parallel.Invoke(options, () =>
            {
                Console.WriteLine("Starting first task");
                Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
                DoFirstTask();
            }, () =>
            {
                Console.WriteLine("Starting second task");
                Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
                DoSecondTask();
                options.CancellationToken.ThrowIfCancellationRequested();
            }, () =>
            {
                Console.WriteLine("Starting third task");
                Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
                DoThirdTask();
            }
            );
        }
        catch (OperationCanceledException ex)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Error Message - {0}", ex.Message);
        }
           
        Console.ReadLine();
    }
    public static void DoFirstTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Total numbers - {0}", numbers.Count());
        Console.WriteLine("First task completed.");
    }
    public static void DoSecondTask()
    {
        List<int> numbers = new List<int>();
        if (numbers.Count <= 0)
        {
            cancelToken.Cancel();
            return;
        }
        Console.WriteLine("Sum of all numbers - {0}", numbers.Sum());
        Console.WriteLine("Second task completed.");
    }
    public static void DoThirdTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Average of all numbers - {0}", numbers.Average());
        Console.WriteLine("Third task completed.");
    }
}
}

Output –


As you can see in above example, CancellationTokenSource and ParallelOptions used to cancel Parallel.Invoke method. This cancellation process is similar to the cancellation process for Parallel.For and Parallel.Foreach. In above example, DoSecondTask method has condition to cancel the Parallel.Invoke method. Once this condition is true, the parallel options will throw OperationCanceledException and Parallel.Invoke method will be cancelled.

Exception Handling –


Exception handling in Parallel.Invoke is also similar to Parallel.For and Parallel.Foreach. There is no special mechanism provided by Task Parallel Library to handle exceptions. We can use try catch block to catch exception inside parallel.invoke method. 

See below modified code to handle exceptions.

Code –
namespace ParallelInvoke
{
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    public static ConcurrentQueue<Exception> exceptionQueue = new ConcurrentQueue<Exception>();
    static void Main(string[] args)
    {
        try
        {
            Parallel.Invoke(() =>
            {
                Console.WriteLine("Starting first task");
                Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
                DoFirstTask();
            }, () =>
            {
                Console.WriteLine("Starting second task");
                Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
                DoSecondTask();
                if (exceptionQueue.Count > 0) throw new AggregateException(exceptionQueue);
            }, () =>
            {
                Console.WriteLine("Starting third task");
                Console.WriteLine("Thread ID - {0}", Thread.CurrentThread.ManagedThreadId);
                DoThirdTask();
            }
            );
        }
        catch (AggregateException ex)
        {
            foreach (Exception e in ex.InnerExceptions)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error Message - {0}", e.InnerException.Message);
            }
        }
        Console.ReadLine();
    }
    public static void DoFirstTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Total numbers - {0}", numbers.Count());
        Console.WriteLine("First task completed.");
    }
    public static void DoSecondTask()
    {
        List<int> numbers = new List<int>();
        if (numbers.Count <= 0)
        {
            exceptionQueue.Enqueue(new Exception("numbers list is empty"));
        }
        Console.WriteLine("Sum of all numbers - {0}", numbers.Sum());
        Console.WriteLine("Second task completed.");
    }
    public static void DoThirdTask()
    {
        List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        Console.WriteLine("Average of all numbers - {0}", numbers.Average());
        Console.WriteLine("Third task completed.");
    }
}
}

Output –


As you can see in above example, exception thrown from DoSecondTask method. ConcurrentQueue has been used to safely add multiple exception thrown from multiple threads. Parallel.Invoke method covered with try catch block. So if any exception thrown from delegate, this will enqueue inside ConcurrentQueue and once all tasks are completed, you can check which exceptions occurred by iterating all the InnerException.

You can download full code from Gist.

I hope this article helps you to know more about Parallel.Invoke and Task Parallel Library. Please leave your feedback in comments below.

References –

See Also –