Pranay Rana: September 2015

Monday, September 7, 2015

Collection Interface In .NET

Introduction

.NET framework provides interfaces that implements by collections in language to provide functionality of iterating over objects in collection, adding and removing object from collection to randomly access object from collection.

As different interfaces provide different set of functionality most of the developers has problem when to use which interface to achieve functionality. The following post provides information about interfaces implemented by collection.

Interfaces

The following diagram is for relation between the interfaces.


Note:
  1. Class diagram are not having all the methods but contains important method that belongs to each collection interface.

  2. Collection interface is available in both generic and non-generic form, so in diagram obj type is object in nongeneric form and obj type is T(template type) in generic form.
Functionality Provided Read Count Add & Remove Index Based Read Index Based Add & Remove
IEnumerable
  1. Provide Read only Collection.
  2. Allow to read each object of collection in forward only mode.
Y N N N N
ICollection
  1. Allow to modify collection.
  2. Allow to get size of collection.
  3. Allow to Add and Remove object in/from collection.
Y
Inherited)
Y Y N N
IReadOnlyCollection
  1. Allow to read collection.
  2. Allow to get size of collection.
Y
(Inherited)
Y N N N
IList
  1. Allows to access collection by Index.
  2. Allow to Add and Remove object in/from collection by index.
Y
(Inherited)
Y
(Inherited)
Y
(Inherited)
Y Y
IReadOnlyList Allow to read collection by Index. Y
(Inherited)
Y
(Inherited)
N Y N

Note:
In above diagram (Inherited), the columns indicate that the features are inherited from parent and to find out from which parent one must look in the interface collection diagram.

So from above table three main interfaces functionality concluded in following way:

IEnumerable – interface provide minimum functionality which is Enumration.

ICollection – interface provide medium functionality which is getting size, adding, removing and clearing collection i.e. modification of collection. As it inherited from IEnumerable so includes functionality of IEnumerable.

IList – interface provide full functionality which is index base accessing of collection element, index base adding, index base removing from collection. As it inherited from ICollection it includes functionality of Enumerable and ICollection.

The following are some important things to know:
  1. IEnumerable interface under the hood make use of IEnumerator for providing reaonly and forward mode read.

  2. IReadOnly*** and IEnumerable are used for providing readonly collection. But difference is that IEnumerable allows collection to read in forward only mode where IReadOnly*** provide feature of Collection /List but only in readonly mode i.e. without modification feature like add & remove.

  3. IReadOnly is part of collection interface from framework 4.5.
Above table list down the features provided by each interface when collection gets converted to interface type or class implement interface to provide feature of collection.

Conclusion

It’s very important for developers to understand these interfaces because the rule says its always good to depend on interface rather than on the concrete type.

ContinueWith Vs await

TPL is new library introduced in C # 4.0 version to provide good control over thread, to make use of multicore CPU by mean of parallel execution on thread. Below discussion is not about TPL but its about ContinueWith function available on Task Class of TPL and await keyword introduced in C# 5.0 to support asynchronous calls.

ContinueWith - its method available on the task which allows executing code after task finished execution. In simple word it allows continuation.

Things to note here is ContinueWith also return one Task. That means you can attach ContinueWith on task return by this method.

Example :
public void ContinueWithOperation()
{
   Task<string> t = Task.Run(() => LongRunningOperation("Continuewith", 500));
   t.ContinueWith((t1) =>
   {
       Console.WriteLine(t1.Result);
   });
}

In above code new created task runs LongRunningOperation and once task execution completed ContinueWith execute operation on retuned task and print result of task.

ContinueWith operation thask get executed by default thread scheduler, one can also provide other scheduler for running task on it, this discussed in later in this article.

Note: below code is LongRunningOperation called by task. LongRunningOpertion here is just example in real program one cannot call long running operation on task, and if one want to call longrunning task than one need to pass TaskCreationOperation.LongRunning.

private string LongRunningOperation(string s, int sec)
{
  Thread.Sleep(sec);
  return s + " Completed";
}

await – its keyword that cause runtime to run operation on new task and cause executing thread to return and continue with execution (In most of the cases executing that is main thread of application). Once await operation get finished it returns to statement where is left of (i.e. returns to caller i.e. it returns according state saved) and start executing statements.

So await wait for newly created task to finish and ensures continuation once execution of waiting task is finished.

await keyword used with async to achieve asynchronous programming in C#. It’s called asynchronous programming because runtime capture state of program when it encounter await keyword (which is similar to yield in iterator) and restore state back once waited task finish so the continuation runs on correct context.

Example :

public async void AsyncOperation()
{
    string t = await Task.Run(() => LongRunningOperation("AsyncOperation", 1000));
    Console.WriteLine(t);
}

In above example new created task calls LongRunningOperation and execution left of once main thread encounter await keyword i.e. main thread return to caller of AsyncOpetion and execute further. Once LongRunningOpertaion completed than result of task get printed on console.

So here because state saved when await encountered flow returns on same context one operation on task executed.

Note: State is having detail about executioncontext/synchronizationcontext.

So form above its clear that both Task.ContinueWith and await Task wait for task to finish and allows continuation after task completion. But both works differently.

Difference between ContinueWith and await
  1. Saving Sate for And return on Execution context
    ContinueWith doesn’t save any kind of state, continuation operation attached using ContinueWith run on default thread scheduler in case not scheduler provided.

    await – on encounter of this keyword state get saved and once task on which await done get completed execution flow pick up saved state data and start execution statement after await. (Note: State is having detail about executioncontext/synchronizationcontext.)

  2. Posting Completed Task result on UI Control
    Below is example with ContinueWith and await to display completion task result on UI control.

    ContinueWith :

    Consider below code which display result of completed task on UI label.

    public void ContinueWithOperation()
           {
             CancellationTokenSource source = new CancellationTokenSource();
             source.CancelAfter(TimeSpan.FromSeconds(1));
             Task<string> t = Task.Run(() => LongRunningOperation("Continuewith", 500
    ));
    
                t.ContinueWith((t1) =>
                {
                    if (t1.IsCompleted && !t1.IsFaulted && !t1.IsCanceled)
                        UpdateUI(t1.Result);
                });
    }
    
    private void UpdateUI(string s)
           {
             label1.Text = s;
    }
    Note : LogRunningOperation is already given above.

    When above code is get executed below runtime exception occurs.



    This exception occurs because Continuation operation UpdateUI operation runs on different thread, in this case thread will be provided by default threadschedular which is ThreadPool and it doesn’t have any information about Synchronization context on which to run.

    To avoid exception, one must need to pass thread scheduler which pass data on UI SynchronizationContenxt. In below code TaskScheduler.FromCurrentSynchronizationContext() method pass UI related thread scheduler.

    t.ContinueWith((t1) =>
                {
                    if (t1.IsCompleted && !t1.IsFaulted && !t1.IsCanceled)
                        UpdateUI(t1.Result);
                }, TaskScheduler.FromCurrentSynchronizationContext());


    await :

    Consider below code which display result of completion on UI.

    public async void AsyncOperation()
    {
        try
        {
           string t = await Task.Run(() => LongRunningOperation("AsyncOperation",
                            10000));
           UpdateUI(t);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }


    Code written with await doesn’t throw any exception when posting data to UI control, No special code required for await. This happens because as discussed in 1 point of difference , on encounter of await state data get saved which has information about SynchronizationContext.

    So if one need to post data on UI than await is good option because there is no need of extra care/code to post data on UI.


  3. Handling Exception and Cancellation
    Consider below example code for ContinueWith and await method for handing exception and cancelled task.

    ContinueWith

    Below is example code how the exception/cancellation handled using ContinueWith.

    public void ContinueWithOperationCancellation()
           {
                CancellationTokenSource source = new CancellationTokenSource();
                source.Cancel();
    
                Task<string> t = Task.Run(() =>
                    LongRunningOperationCancellation("Continuewith", 1500,
                        source.Token), source.Token);
    
                t.ContinueWith((t1) =>
                {
                    if (t1.Status == TaskStatus.RanToCompletion)
                        Console.WriteLine(t1.Result);
                    else if (t1.IsCanceled)
                        Console.WriteLine("Task cancelled");
                    else if (t.IsFaulted)
                    {
                        Console.WriteLine("Error: " + t.Exception.Message);
                    }
                });
    }

    In above code cancellation/exception in continuation handled with by using TaskStatus. Other way to do same thing by making use of TaskContinuationOptions.OnlyOnRanToCompletion

    t.ContinueWith(
        (antecedent) => {  },
         TaskContinuationOptions.OnlyOnRanToCompletion);

    await

    Below is example code how the exception/cancellation handled using await.

    public async void AsyncOperationCancellation()
           {
             try
             {
               CancellationTokenSource source = new CancellationTokenSource();
               source.Cancel();
               string t = await Task.Run(() =>
                   LongRunningOperationCancellation("AsyncOperation", 2000, source.Token),
                       source.Token);
                    Console.WriteLine(t);
             }
             catch (TaskCanceledException ex)
             {
                    Console.WriteLine(ex.Message);
             }
             catch (Exception ex)
             {
                    Console.WriteLine(ex.Message);
             }
    }


    Above code doesn’t make use of task status as continuewith, it makes use of try ..catch block to handle exception. To handle cancellation there is need of catch block with TaskCanceledException.

    So from above example my view is cancellation/exception handling is done very clean way when one use continuation.

    Below is code for LongRunningOperationCancellation method.

    private string LongRunningOperationCancellation(string s, int sec,CancellationToken ct)
           {
             ct.ThrowIfCancellationRequested();
             Thread.Sleep(sec);
             return s + " Completed";
    }


    Above three cases shows difference of coding between ContinueWith and await. But below one shows why await is better than ContinueWith.

  4. Complex flow
    Consider below function which used for calculation factorial of number

       public KeyValuePair<int, string> Factorial(int i)
            {
                KeyValuePair<int, string> kv;
                int fact = 1;
                for (int j = 1; j <= i; j++)
                    fact *= j;
                string s = "factorial no " + i.ToString() + ":" + fact.ToString();
                kv = new KeyValuePair<int, string>(i, s);
                return kv;
            }
    Above function calculate factorial of number and return KeyValuePair to caller to display calculation.

    Now problem statement is above function to calculate factorial of number 1 to 5.

    ContinueWith

    Below is code to calculate factorial of numbers between 1 to 5. Expectation from the code below is calculating factorial of number, display it in order and once it completed “Done” message will get printed on the console.

    public void ContinueWithFactorial()
           {
                for (int i = 1; i < 6; i++)
                {
                    int temp = i;
                    Task<KeyValuePair<int, string>> t = Task.Run(() => Factorial(temp));
                    t.ContinueWith((t1) =>
                    {
                        KeyValuePair<int, string> kv = t1.Result;
                        Console.WriteLine(kv.Value);
                    });
                }
                Console.WriteLine("Done");
    }


    Once code get executed one will find that “Done” message get printed immediately i.e. first than factorial of number get displayed on screen. One more problem is number factorial is not get displayed in order. Below is output of the code execution.



    So to resolve problem with above code , code need to be refactored like this

    public void FactContinueWithSeq(int i)
    {
                Task<KeyValuePair<int, string>> t = Task.Run(() => Factorial(i));
                var ct = t.ContinueWith(((t1) =>
                {
                    KeyValuePair<int, string> kv = t1.Result;
                    int seed = kv.Key;
                    if (seed < 6)
                    {
                        Console.WriteLine(kv.Value);
                        seed++;
                        FactContinueWithSeq(seed);
                    }
                    else
                    {
                        Console.WriteLine("Done");
                        return;
                    }
                }));
    }


    Above function will be called like this p.FactContinueWithSeq(1).

    In above code to maintain sequence, task need to be fired one by one. And for that once one task completes its execution Contuation on it with the help of ContinueWith method call function again. It’s like doing recursive calling to function.

    And to display “Done” message at the end need to check for the seed to function. Which checks seed value increases 6 or not.



    But now there is need for attaching continuation on completion of FactContinueWithSeq, to achieve this code need to be done as below.

    TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
            public Task<string> FactAsyncTask { get { return tcs.Task; } }
            public void FactContinueWithSeqAsync(int i)
            {
                Task<KeyValuePair<int, string>> t = Task.Run(() => Factorial(i));
                var ct = t.ContinueWith(((t1) =>
                {
                    KeyValuePair<int, string> kv = t1.Result;
                    int seed = kv.Key;
                    if (seed < 5)
                    {
                        Console.WriteLine(kv.Value);
                        seed++;
                        FactContinueWithSeqAsync(seed);
                    }
                    else
                    {
                        tcs.SetResult("Execution done");
                    }
                }));
            }

  5. Call to above function

    p.FactContinueWithSeqAsync(1);
                Task<string> t = p.FactAsyncTask;
                t.ContinueWith((t1)=> Console.WriteLine(t.Result));


    In above code TaskCompletionSource is used to achieve the code of providing continutation on completion of factorial calculation.

    So one need to do lot of code for providing expected result, which is calculating factorial in sequence, waiting on calculation and once calculation get completed “Done” message get printed on console.

    await

    Now same code with help of await can be done like this

    public async void AwaitWithFactorial()
    {
       for (int i = 1; i < 6; i++)
       {
           int temp = i;
           Task<KeyValuePair<int, string>> t = Task.Run(() => Factorial(temp));
           await t;
           Console.WriteLine(t.Result.Value);
          }
          Console.WriteLine("Done");
     
    }


    Above code is simple and clean there is no need of doing whole big refactoration which required when doing same thing with ContinueWith.

Summary

From above difference/comparison of ContinueWith vs await it clear that in many scenario using and await is very helpful.
But there is also scenario where more complex things not required with proper error/cancellation handling in that case continuewith is helpful. But this scenario is very rare.

It’s always good to go with simple, easy and clear solution, for this my suggestion is always go with await rather than ContinueWith.

Flyweight Design Pattern

The Flyweight Design Pattern is one of the structural patterns introduced by the GOF. The Flyweight Pattern is about creating a pool of objects that allows sharing already existing objects and causing the application to consume less memory.

So this pattern does the following two things because the pattern creates objects once and then saves them to a pool:
  1. Increases application performance in terms of object creation since there is no requirement of creating an object for every request.
  2. Causes the application to consume less memory, since the object already exists in memory and no new object must be created because of the pool.
Ultimately flyweight patterns make the application efficient in terms of memory and processing.

Basic UML class Diagram of Design Pattern

The following image shows the class diagram of the basic Flyweight Design Pattern.



UML class Diagram
  • IFlyweight: Basic contract to be implemented by derived types, in other words by concrete flyweight.
  • FlyweightFactory: It's a factory class used by a client class to get the data from the concreate flyweight. This class is also responsible for creating the pool of an existing object. So when the request for data come that is already requested it returns data from the pool.
  • ConcerateSharedFlyweight1: It's a concreate implementation of the flyweight interface. As the name suggests, an object returned by this class will be shared among the clients of it.
  • ConcerateUnSharedFlyweight1: It's a concreate implementation of the flyweight interface. As the name suggests an object returned by this class will be unshared. That means that every time the client requires a new object.
  • Client: uses the concreate implementation, it creates an instance of Decorate and uses the functionality of it.
Note:UnSharedFlyweight is not always required, it depends on requirements, but SharedFlyweight is always required when you use the flyweight pattern.

The following code is the implementation of the Flyweight Design Pattern and the Class Diagram was shown above.

namespace BasicFlyweightPattern
{
    #region basic implementation
    public class FlyweightFactory 
    {
        public static List<Item> GetStaticItemList(string key)
        {
            IFlyWeight flyWeight = null;
            ICacheManager _objCacheManager = CacheFactory.GetCacheManager();

            if (key == "A")
            {
                if (_objCacheManager.Contains("A"))
                {
                    return _objCacheManager["A"] as List<Item>;
                }
                else
                {
                    flyWeight = new ConcerateSharedFlyweight1();
                }
            }
            else if (key == "B")
            {
                if (_objCacheManager.Contains("B"))
                {
                    return _objCacheManager["B"] as List<Item>;
                }
                else
                {
                    flyWeight = new ConcerateSharedFlyweight2();
                }
            }

            var list = flyWeight.GetList();
            _objCacheManager.Add(key, list);
            return list;
        }
    }

    interface IFlyWeight
    {
        List<Item> GetList();
    }

    public class Item
    {
        public int id { get; set; }
        public string desc { get; set; }
    }

    public class ConcerateSharedFlyweight1 : IFlyWeight
    {
        private List<Item> ItemList;

        public ConcerateSharedFlyweight1()
        {
            ItemList = new List<Item>();
        }

        public List<Item> GetList()
        {
            ItemList.Add(new Item { id = 1, desc = "A1" });
            ItemList.Add(new Item { id = 2, desc = "A2" });
            ItemList.Add(new Item { id = 3, desc = "A3" });
            return ItemList;
        }
    }

    public class ConcerateSharedFlyweight2 : IFlyWeight
    {
        private List<Item> ItemList;

        public ConcerateSharedFlyweight2()
        {
            ItemList = new List<Item>();
        }

        public List<Item> GetList()
        {
            ItemList.Add(new Item { id = 1, desc = "B1" });
            ItemList.Add(new Item { id = 2, desc = "B2" });
            ItemList.Add(new Item { id = 3, desc = "B3" });
            return ItemList;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Item> list =FlyweightFactory.GetStaticItemList("A");
     //List<Item> list = FlyweightFactory.GetStaticItemList("B");            
     foreach (var item in list)
            {
                Console.WriteLine(item.id.ToString() + "  " + item.desc );
           }

            Console.ReadLine();
        }
    }

}
      
The following are points to remember about the preceding code implementation:
  1. The client asks for data from FlyweightFactory by calling GetStaticItemList and passing the key as argument for getting the data.
  2. FlyweightFactory has a static method GetStaticItemList that creates an instance of concrete and gets data if the request is for the first time, for a later request it returns an existing object.
  3. FlyweightFacotry maintains a pool of existing objects using an Enterprise library caching block for sharing data among the clients, in other words different objects.
  4. In the concrete implementation of flyweight, a hardcoded list is returned but in an actual scenario this will be replaced by data from a data source.
  5. Item is a poco class, the list of which is returned from flyweight concrete classes. This class is represented by different items. The following actual scenario provides more detail.
Output



Here the output shows the result of A's same will use the result of B's. If the call comes a second time then the data is retuned from the cache.

Flyweight Design Pattern Example In an Actual Application

Problem Statement

A web application having a dropdown for displaying a list of Country, displaying a list of State, displaying a list of Product and so on in the dropdown and the dropdowns are part of multiple screens that are accessed by multiple users.

In this scenario, to display another kind of list for multiple user requests, the server must connect with the database server multiple times. This reduces the performance of the application and also consumes memory for creating and storing these lists.

Solution

The solution to the preceding problem is to use the Flyweight Design Pattern.

The following is a class diagram of the Flyweight pattern used in the application.


 
Mapping with Basic Implementation.
  • IFlyweightManager is equals to IFlyweight.
  • StaticDataListFlyweightFactory is equal to FlyweightFactory.
  • CountryStaticListManager and ProductStaticListManager is equal to ConcerateSharedFlyweight1 and ConcerateSharedFlyweight2.
  • StaticItem is equal to Item.
namespace FlyWeightPattern
{
    class Program
    {
        static void Main(string[] args)
        {

            List<StaticItem> countrylist = StaticDataListFlyWeidhtFactory.GetStaticItemList("Country");
            foreach (var item in countrylist)
            {
                Console.WriteLine(item.id.ToString() + "  " + item.Code + "  " + item.Description);
            }

            Console.ReadLine();
        }
    }
 public class StaticDataListFlyWeidhtFactory
    {
        public static List<StaticItem> GetStaticItemList(string key)
        {
            IFlyWeightManager manager = null;
            ICacheManager _objCacheManager = CacheFactory.GetCacheManager();

            if (key == "Country")
            {
                if (_objCacheManager.Contains("Country"))
                {
                    return _objCacheManager["Country"] as List<StaticItem>;
                }
                else
                {
                    manager = new CountryStaticListManager();
                }
            }
            else if (key == "ProductType")
            {
                if (_objCacheManager.Contains("ProductType"))
                {
                    return _objCacheManager["ProductType"] as List<StaticItem>;
                }
                else
                {
                    manager = new ProductTypeStaticListManager();
                }
            }

            var list = manager.GetList();
            _objCacheManager.Add(key, list);
            return list;
        }
    }

    interface IFlyWeightManager
    {
        List<StaticItem> GetList();
    }

    public class CountryStaticListManager : IFlyWeightManager
    {
        private List<StaticItem> StaticItemList;

        public CountryStaticListManager()
        {
            StaticItemList = new List<StaticItem>();
        }

        public List<StaticItem> GetList()
        {
            StaticItemList.Add(new StaticItem { id = 1, Code = "IND", Description = "India" });
            StaticItemList.Add(new StaticItem { id = 2, Code = "SRL", Description = "Sri Lanka" });
            StaticItemList.Add(new StaticItem { id = 3, Code = "SA", Description = "South Africa" });
            return StaticItemList;
        }
    }

    public class ProductTypeStaticListManager : IFlyWeightManager
    {
        private List<StaticItem> StaticItemList;

        public ProductTypeStaticListManager()
        {
            StaticItemList = new List<StaticItem>();
        }

        public List<StaticItem> GetList()
        {
            StaticItemList.Add(new StaticItem { id = 1, Code = "0123", Description = "Watch" });
            StaticItemList.Add(new StaticItem { id = 2, Code = "0234", Description = "Shoes" });
            StaticItemList.Add(new StaticItem { id = 3, Code = "0345", Description = "" });
            return StaticItemList;
        }
    }

    public class StaticItem
    {
        public int id { get; set; }
        public string Code { get; set; }
        public string Description { get; set; }
    }
}

Output
 


So the preceding code works the same as already described in the basic implementation of pattern. In the code another type of the list is fetched by passing a different key. For this implementation the keys are Country and Product. In a real application one can have more than this.

The preceding implementation follows the SOLID principle, just one exception is the Factory class that must be modifed when one wants to add a new key so it breaks the rule of single responsibility.

Note: Here the country and product list are hardcoded but in an actual program it is fetched from the database.

Conclusion

This pattern is very helpful in the scenario where one wants to create a pool of objects and share them among the clients (the clients are software programs or classes or web applications as in this example).

Note: This is my point of view regarding patterns. Please provide your feedback regarding it and also provide feedback if something you find is wrong in this.