C# Code Example

interface in C#

Most simple implementation of interface:

    public interface ILeft
    {
        void Move();
    }

    public class MoveableOject : ILeft
    {
        //without public we get an error
        public void Move()
        {
            Console.WriteLine("Left moving");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MoveableOject mo = new MoveableOject();
            mo.Move();
            Console.ReadKey();
        }
    }

Explicit interface implementation of interface in C#
We need to implement explicit interface when we need want to tell which interface we are implementing. This may be useful when we have same method in both interfaces that we are going to implement. Consider the example.

    public interface ILeft
    {
        void Move();
    }

    public class MoveableOject : ILeft
    {
          //Se there is no public  and the interface name is visible in front of the method.
        void ILeft.Move()
        {
            Console.WriteLine("Left moving");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //Derived class can't cast to base class
            //MoveableOject moError = (ILeft) new MoveableOject(); //Error??
            //ILeft  moError = new MoveableOject(); //OK moError declared as ILeft
            MoveableOject mo = new MoveableOject();
            ((ILeft)mo).Move();
            ((ILeft)new MoveableOject()).Move(); // same as previous statement
            Console.ReadKey();
        }
    }

Implementing multiple interface in C# explicit way

        public interface ILeft
        {
            void Move();
        }
        public interface IRight
        {
            void Move();
        }

        public class MoveableOject : ILeft, IRight
        {
             void ILeft.Move()
            {
                Console.WriteLine("Left moving");
            }
             void IRight.Move()
            {
                Console.WriteLine("Right moving");
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                MoveableOject mo =   new MoveableOject();
                ((ILeft)mo).Move();
                ((IRight)mo).Move();
                Console.ReadKey();
            }
        }

is and as operator in C#:

The is operator determines whether an object is compatible with a particular type. For example, suppose the Employee class is derived from Person, and the Manager class is derived from Employee. Now suppose the program has a variable named user and it must take special action if that variable refers to an Employee but not to a Person.

The as Operator returns the object if casting is valid. If casting is not valid, it will return null. On the other hand, is operator returns true if the object is derived from a base class.


   public interface IDataContainer
    {
        string Data { get; set; }
    }
    public class CDataContainer : IDataContainer
    {
        private string _data;
        public string Data
        {
            get
            {
                return _data;
            }
            set
            {
                _data = value;
            }
        }
    }

    class MyClass
    {
        public int MyProperty { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            CDataContainer myClass = new CDataContainer();
            myClass.Data = "Hello Mahbub";
            DoWork(myClass);

            MyClass myc = new MyClass();
            DoWork(myc);

            int i = 0;
            DoWork(i);    
        }
        public static void DoWork(Object obj)
        {
            try
            {
                var datacontainer = obj as IDataContainer;
                if (datacontainer != null)
                {
                    Console.WriteLine(datacontainer.Data);
                }
            }
            catch (Exception ) {}

            try
            {
                var datacontainer = obj is IDataContainer;
                if (datacontainer == true)
                {
                    Console.WriteLine("obj is data container");
                }
                else
                {
                    Console.WriteLine("obj is not data container");
                }
            }
            catch (Exception) {}

            try
            {
                var datacontainer = (IDataContainer)obj;
                if (datacontainer != null)
                {
                    Console.WriteLine("obj is data container");
                }
                else
                {
                    Console.WriteLine("obj is not data container");
                }
            }
            catch (Exception)
            {
                Console.WriteLine("obj is not data container");
            }
        }
    }

Using Widening and Narrowing Conversions in C#

In a widening conversion, the destination data type can hold any value provided by the source data type. In a narrowing conversion, the destination data type cannot hold all possible values held by the source data type.
For example, an int variable can hold integer values between –2,147,483,648 and 2,147,483,647. A short variable can hold integer values only between –32,768 and 32,767. That means converting from a short to an int is a widening conversion because an int can hold any value that a short can hold. A widening conversion always succeeds.
In contrast, converting from an int to a short is a narrowing conversion because a short cannot hold every possible value in an int. That doesn’t mean a narrowing conversion from an int to a short will always fail, however. If an int variable happens to hold a value that can fit in a short, such as 100 or 13,000, the conversion succeeds. If the int holds a value that won’t fit in a short, such as 70,000, the conversion fails

C# throws an exception for invalid narrowing integer conversions in a couple ways

A. Checked

checked
{
 int big = 1000000;
 short small = (short)big;
}

Within the checked block, the program throws an OverflowException if the conversion from the int big to the short small fails. A checked block does not protect code inside methods called within the block. For example, suppose the code inside a checked block calls the CalculateTaxes method. In that case the checked block does not protect the CalculateTaxes method if it performs a narrowing conversion. If CalculateTaxes tries to make a narrowing conversion that fails, the program does not throw an exception.

B. By using advanced build setting in Visual Studio

Indexer in C#
Indexed properties, or indexers, behave a little differently from standard properties. The primary purpose of indexed properties is to allow "array-like access to groups of items".


    public class IPAddress
    {
        private int[] ip;

        public IPAddress()
        {
            ip = new int[32];
        }
        public int this[int index]
        {
            get
            {
                return ip[index];
            }
            set
            {
                if (value == 0 || value == 1)
                    ip[index] = value;
                else
                    throw new Exception("Invalid value");
            }
        }
    }

    class Program

    {
 static void Main(string[] args)
    {
        IPAddress myIP = new IPAddress();

        // initialize the IP address to all zeros
        for (int i = 0; i < 32; i++)
        {
            myIP[i] = 0;
        }
    }
}

Here are some key points to keep in mind for indexed properties:
➤ They accept an index value in place of the standard property value parameter.
➤ They are identified through the use of the keyword this.
➤ Indexed properties can be created in classes or structs.
➤ Only one indexed property can exist in a single class or struct.
➤ They can contain get and set methods just like other properties.

C# Optional parameters during method calls (Optional and Named Parameters)
Arguments -> those variables are passed to method calls.

For example, int retvalue = myMethod(23, 4); // 23 and 4 are arguments

int myMethod(int Length,  int Width) // Length  and Width are parameter
{
return  Length * Width;
}

Optional parameters are a feature of methods that enables us to require only some arguments be
passed in to a method while making others optional. Calling a method with optional parameters
means that the caller must provide required parameters but can omit the optional parameters. In the following method Width is optional, if the caller does not supplied Width then 1 will be used.

int myMethod(int Length,  int Width = 1) 
{
return  Length * Width;
}

In the previous example Length is required parameter that must be supplied by the caller. The above method can be called in the following manner.

For example, int retvalue = myMethod(23, 4); 
or
int retvalue = myMethod(23);  // 23 and 1 will be used to calculate the area

In the parameter declaration, required parameters should be placed in first and then followed by optional parameters.
Following code will generate compiler errors since the default parameters are at first.

int myMethod( int Width = 1, int Length) 
{
return  Length * Width;
}

In the call to the myMethod() method, we can pass in the two arguments required, but use the
named arguments length: and width:.


 int retvalue = myMethod(Length:23, Width:4); //Arguments are in same order as parameters list
 int retvalue = myMethod(Width :4, Length:23); //Arguments are not in same order as parameters list

Note the order of arguments can be different as compared to parameters list. Now if some parameters are not named they must appear first. The following code is valid. Look the other parameter is the first in parameter list. If we put other at the end, we get compiler error.

    class Program
    {
        static void Main(string[] args)
        {
            double area = rectArea(0, width: 5.0, length: 2.0);
            Console.WriteLine(area);
            Console.ReadKey();
        }
        public static double rectArea(int other, double length, double width )
        {
            return length * width;
        }       
    }

Delegate in C# is as function pointer in C++. However there are some differences between function pointer and delegate. For example delegate supports chaining. Here is a declaration of delegate.

public delegate int MyDelegate ( int x, int y );

Example, how to use delegate

//We can declare inside class as well
public delegate int MyDelegate ( int x, int y );

public class myApp
{
    public static void Main ( )
    {
        MyDelegate del = new MyDelegate ( Add );
        int result = del ( 3, 4);
        Console.WriteLine ( "The result1 is = {0}", result );

        //See how we can use Invoke method
        result = del.Invoke ( 5, 6 );
        Console.WriteLine ( "The result2 is = {0}", result );

        //Avoid using new, it is done by compiler automatically
        // See Add has () but it is OK without () as well
        MyDelegate del2 = (Add );
        result = del ( 8, 10 );
        Console.WriteLine ( "The result3 is = {0}", result );

        //Now Del2 points to Add method, add more method
        del2 += Sub;
        del2 += Mul;

        result = del2.Invoke ( 40, 30 );
        //See the result is coming from the last operation (Mul) not from Sub or Add
        Console.WriteLine ( "The result4 is = {0}", result );

        //Call without invoke, in both case see that Add, Sub and Mul methods are called
        result = del2( 40, 30 );
        //See the result is coming from the last operation (Mul) not from Sub or Add
        Console.WriteLine ( "The result5 is = {0}", result );

        //Pass delegate to other method
        result = PassDel ( del2 );
        Console.WriteLine ( "The result6 is = {0}", result );
    }

    public static int Add(int x, int y)
    {
        Console.WriteLine ( "Inside  Add method" );
        return x + y;
    }

    public static int Sub ( int x, int y )
    {
        Console.WriteLine ( "Inside  Sub method" );
        return x - y;
    }

    public static int Mul ( int x, int y )
    {
        Console.WriteLine ( "Inside  Mul method" );
        return x * y;
    }

    public static int PassDel (MyDelegate del )
    {
        Console.WriteLine ( "Inside  PassDel method" );
        int ret = del ( 20, 10 );
        return ret;
    }
}

Anonymous Functions, a function without name. We can reduce the size of code by using anonymous methods. Let's modify the previous example.

class app
{
    public delegate int MyDelegate ( int x, int y );
    public static void Main ( )
    {
        //we have removed Add method implementation totally by intruducing anonymous method
        //We don't need to have the Add method at all.
        MyDelegate del = delegate ( int x, int y ) { return x + y; };
        int result = del ( 2, 4 );
        Console.WriteLine ( result );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                break;
            }
        }
    }

    public static int Add ( int x, int y )
    {
        Console.WriteLine ( "Inside  Add method" );
        return x + y;
    }

    public static int Sub ( int x, int y )
    {
        Console.WriteLine ( "Inside  Sub method" );
        return x - y;
    }

    public static int Mul ( int x, int y )
    {
        Console.WriteLine ( "Inside  Mul method" );
        return x * y;
    }
}

Sometimes the whole signature of a method can be more code than the body of a method. There are also situations in which you need to create an entire method only to use it in a delegate. Anonymous functions can be further shortened by Lambda expression.


class app
{
    public delegate int MyDelegate ( int x, int y );
    public static void Main ( )
    {
        //we have removed Add method implementation totally by intruducing Lambda expression
        //We are not using anonymous method keyword delegate anymore
        MyDelegate del = ( int x, int y ) =>  x + y; 
        // equivalent
        //MyDelegate del = (  x, y ) => x + y; 
        int result = del ( 25, 4 );
        Console.WriteLine ( result );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                break;
            }
        }
    }
}

We can create lambdas that span multiple statements. We can do this by adding curly braces around the statements that form the lambda as following example shows.

class app
{
    public delegate int MyDelegate ( int x, int y );
    public static void Main ( )
    {
        //we have removed Add method implementation totally by intruducing Lambda expression
        //We are not using anonymous method keyword delegate anymore
        MyDelegate del = ( int x, int y ) => 
        {
            Console.WriteLine ( "Lambda Statements" );
            return x + y; 
        };

        int result = del ( 25, 4 );
        Console.WriteLine ( result );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                break;
            }
        }
    }
}

Action is generic delegate specified by .NET framework. If we use this we don't need to declare the delegate by ourselves.

    class program
    {     
        static void Main ( )
        {
            Action<int, int > del = ( int x, int y ) =>
            {
                Console.WriteLine ( "Data received {0}, {1}", x, y );
            };
            del (5 , 6);
       
            Console.ReadKey ( );
        }
    }

Func is very much similar to Action. Only difference is that Func can return a value. Following example takes an integer parameter and return a string.

    class program
    {     
        static void Main ( )
        {
            Func<int , string >del = ( int y ) =>
            {
                Console.WriteLine ( "Data received {0}",  y );
                return "Mahbub Rahman";
            };
            Console.WriteLine(del(5));                 
            Console.ReadKey ( );
        }
    }

Following example takes 2 integer parameters and return a string by using Func.

    class program
    {     
        static void Main ( )
        {
            Func<int, int, string> del = ( int x, int y ) =>
            {
                Console.WriteLine ( "Data received x = {0}, y = {1}", x, y );
                return "Mahbub Rahman";
            };
            Console.WriteLine(del(5, 7));                 
            Console.ReadKey ( );
        }
    }

Difference between Func and Action is that in Func the last last one should be return type, in Func there must be a return statement. See the following example. double type is returned, so the second generic parameter is double and the return type of the lambda statement is double. Also note that the result is declared as double. Only one parameter is passed to OwnedFunc and that is int type though in declaration we have 2 parameters.

class app
{ 
    public static void Main ( )
    {
        Func<int, double> OwnedFunc = ( int x) =>
        {
            Console.WriteLine ( "Data received {0}", x );
            return 100 * x; //implicitly converted to double
        };

        double result = OwnedFunc ( 5 );
        Console.WriteLine ( "result = {0}", result );

        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                break;
            }
        }
    }
}
//Multiple parameters with Func
namespace Chapter1.Threads
{
    class TaskAsyncExample
    {
        public static void Main()
        {
            Func<int, double> fn = ((x) => { return 100.0 * x; });
            Func<int, double> fn2 = delegate (int x) { return 100.0 * x; };
            //Convert first two integers  and return as string
            Func<int, int, string> fn3 = delegate (int x, int y) { return "fn3 " + x.ToString() + " " + y.ToString(); };
            Func<int, int, string> fn4 = ((int x, int y) => { return "fn4 " + x.ToString() + " " + y.ToString(); });
            string d = fn3(3, 3);
            Console.WriteLine(d);
            Console.ReadKey();
        }
    }
}

More on Func<t1, out t2> and Task<TResult>
Func is generic delegate that takes up to 18 parameters and always the last one is out parameter. All other parameters are in parameters. For example in the following code, first int is input parameter and second string is out parameter, meaning the return value of the delegate.

Func<int, string> fn = (int x) => { return "Hello Mahbub " + x.ToString(); };
namespace Chapter1.Threads
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int, string> fn = (int x) => { return "Hello Mahbub " + x.ToString(); };
            string myretstring = fn(4);
            Console.WriteLine(myretstring);
            string str = null;
            Task<string> tfn = Task<string>.Factory.StartNew(() => str = fn(10));
            Console.WriteLine("tfn.result = " + tfn.Result);
            Console.ReadKey();
        }
    }
}

First myretstring variable is declared as string that will hold the return value of Func. The return value is saved directly to myretstring. Looks how 4 is passed to the Func. Second, we create a Task that return result as string. StartNew takes a Lambda expression which in turn calls another Func with parameter 10.
There are quite many ways to create task in C#. Following code sample shows four different ways to create task and task<TResult>. We use task when we don't need any return value from operation. When we use Func then we expect return value from operation. StartNew is the most flexible way.
3 ways to create tasks in C#.

namespace Chapter1.Threads
{
    class TaskAsyncExample
    {
        public static void Main()
        {
            //1 1st way to create Task
            Func<int> ac = new Func<int>(GetResult);
            Task<int> t = new Task<int>(ac);
            t.Start();

            //2. 2nd way to create Task, start the task when called StartNew()
            //Func<int> ac = new Func<int>(GetResult);
            //Task<int> t = Task<int>.Factory.StartNew(ac);

            //3. 3rd way to create task, the task start automaticall
            //Task<int> t = Task<int>.Run( () => GetResult());

            //4. 4th way to start tasks
            //Func<int> ac = new Func<int>(GetResult);
            //Task<int> t = Task<int>.Run(ac);

            Console.WriteLine(t.Result);
            Console.ReadKey();
        }
        private static int GetResult()
        {
            Console.WriteLine("Task is being executed");
            return 200;
        }
    }
}

Events in .NET framework. Events in .NET are similar to popular design pattern publish and subscribe in many platforms. We can get called when some thing interested happen some where in our code. We can subscribe to an event and then we can be notified when the publisher of the event raises a new event. This is used to establish loose coupling between components in an application. We use delegate and event to accomplished this. Let's design an example, we want to get notified when the balance of an bank account goes below 0.
Declare a delegate, return type void and takes 2 parameters source (who fires the event) and eventargs extra information about the event.

 public delegate void OverdrawnEventHandler (object source, EventArgs eventargs );

Declare an event in the BankAccount class. By Overdrawn we can call the method to which OverdrawnEventHandler points.

public event OverdrawnEventHandler Overdrawn;
public class BankAccount
{
   public delegate void OverdrawnEventHandler (object source, EventArgs eventargs );
  //public delegate void EventHandler ( object sender, TEventArgs e );
   public event OverdrawnEventHandler Overdrawn;
  // public event EventHandler Overdrawn;
    public decimal Balance { get; set; }

    public void Credit ( decimal amount )
    {
        Balance += amount;
    }
    public void Debit ( decimal amount )
    {
        if (Balance >= amount)
        {
            Balance -= amount;
        }
        else
        {
            if (Overdrawn != null)
            {
                Overdrawn ( this, new OverdrawnEventArgs ( Balance, amount ) );
            }
        }
    }
}

public class OverdrawnEventArgs : EventArgs
{
    public decimal CurrentBalance, DebitAmount;
    public OverdrawnEventArgs ( decimal currentBalance, decimal debitAmount )
    {
        CurrentBalance = currentBalance;
        DebitAmount = debitAmount;
    }
}

public class myApp
{
    public static void Main ( )
    {
        BankAccount bc = new BankAccount ( );
        bc.Credit ( 30 ); // we deposit 30 € 
       // we are chaining by delegate, when overdrawn happens bc_Overdrawn is called
        bc.Overdrawn += bc_Overdrawn; 
        bc.Debit ( 200 ); // we over draw 200€
    }

    static void bc_Overdrawn ( object source, EventArgs eventargs )
    {
        OverdrawnEventArgs arg = (OverdrawnEventArgs)eventargs;
        Type type = source.GetType();
        Console.WriteLine ( "Amount overdrawn: Balance = {0}, Amount = {1}", arg.CurrentBalance, arg.DebitAmount );
    }
}

Thread is a unit of execution.

public class myApp
{   
    public static void ThreadMethod()
    {
        for(int i = 0; i < 10; i++)
        {
            Console.WriteLine ( "ThreadProc: {0}", i );
            Thread.Sleep ( 0 );
        }
    }
    public static void Main ( )
    {
        //ThreadStart is a delegate of void function that take no parameters
        //new Thread ( ThreadMethod  ); should work also for the following code
        Thread t = new Thread ( new ThreadStart ( ThreadMethod ) );
        t.Start ( );
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine ( "Main Thread: {0}", i );
            Thread.Sleep ( 0 );
        }
        //wait for the thread to finish
        t.Join ( );
        Console.ReadKey ( );
    }
}

By default a thread is foreground thread, a thread can be set to background by putting IsBackground property to true. A process will stops when all foreground threads are stopped. Try the following example by changing the IsBackground property. If it is background then it stops immediately otherwise it continue to run.

public class myApp
{   
    public static void ThreadMethod()
    {
        for(int i = 0; i < 10; i++)
        {
            Console.WriteLine ( "ThreadProc: {0}", i );
            Thread.Sleep ( 1000 );
        }
    }
    public static void Main ( )
    {
        //ThreadStart is a delegate of void function that take no parameters
        Thread t = new Thread ( new ThreadStart ( ThreadMethod ) );     
        //change to background thread, see property should be set before start the thread
        t.IsBackground = true;
        t.Start ( );
    }
}

The Thread constructor has another overload that takes an instance of a ParameterizedThreadStart
delegate. The parameter is passed when we start the thread.

public class myApp
{
    public static void ThreadMethod ( object obj)
    {
        int num = (int)obj;
        for(int i = 0; i <  num; i++) 
        {
            Console.WriteLine ( "ThreadMethod {0}", i );
            Thread.Sleep ( 0 );
        }
    }

    public static void Main ( )
    {
        // Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod)); should work as well
        Thread t = new Thread (  ThreadMethod  );
        //Pass the object to the Thread in start method
        t.Start ( 10);
        t.Join ( );
    }
}

A thread can have its own data that’s not a local variable. By marking a field with the
ThreadStatic attribute, each thread gets its own copy of a field. Meaning if the [ThreadStatic] attribute is not used the field is common to all threads. If the attribute is used then the field is used as local to the thread. With ThreadStatic the first thread get the initialized value and others thread get the field value as 0.

public class myApp
{
     [ThreadStatic]
    public static int counter = 300;

    public static void Main ( )
    {
        Console.WriteLine ( "With ThreadStatic" );
        Console.WriteLine ( "Main Thread counter {0}", counter );
        new Thread ( ( ) => 
        {
            for (int i = 0; i < 5; i++ )
            {
                Console.WriteLine ( "Thread A is running {0}", counter );
                counter++;
            }
        } 
        ).Start ( );

        new Thread ( ( ) =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine ( "Thread B is running {0}", counter );
                counter++;
            }
        }
        ).Start ( );


        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine ( "Main Thread  is running {0}", counter );
        }
        Console.ReadKey ( );
    }
}

The following image shows the output with ThreadStatic and without ThreadStatic attribute.

 ThreadLocal class takes a delegate to a method that initializes the value for each thread. As compared to ThreadStatic each thread has a unique value.

public class myApp
{
    public static ThreadLocal< int>  _field =
        new ThreadLocal< int>  ( ( ) =>
        {
            return Thread.CurrentThread.ManagedThreadId;
        } );

    public static void Main ( )
    {
        Console.WriteLine ( "Main Thread value {0}", _field.Value );
        new Thread ( ( ) => 
        {
            for (int i = 0; i <  _field.Value; i++)
            {
                Console.WriteLine ( "Thread A  value {0}", _field.Value );   
            }
        } 
        ).Start ( );

        new Thread ( ( ) =>
        {
            for (int i = 0; i <  _field.Value; i++)
            {
                Console.WriteLine ( "Thread B value {0}", _field.Value );   
            }
        }
        ).Start ( );

        for (int i = 0; i <  _field.Value; i++)
        {
            Console.WriteLine ( "Main Thread value {0}", _field.Value );
        }
        Console.ReadKey ( );
    }
}

Thread pools are used to reuse threads since creation thread is expensive somehow. One of the important method is QueueUserWorkItem that takes a delegate with a parameter object. Problem with thread pool is that there is no way to know when the operation is finished or what is the return value.

public class myApp
{
    static bool stop = false;
    public static void Main ( )
    {        
        ThreadPool.QueueUserWorkItem ( ( o) => 
        {
            while (!stop)
            {
                Console.WriteLine ( "ThreadPool thread working" );
            }
        } );

        Console.ReadKey ( );
        stop = true;
    }
}

QueueUserWorkItem only takes a delegate or a delegate and an object. The delegate can be also be lamda expression. See the following example. QueueUserWorkItem takes a delegate which takes a parameter of type object. It may take also 2 parameters.

namespace Chapter1.Threads
{
    class Program
    {
        static void Main(string[] args)
        {
            int result = 0;
           // ThreadPool.QueueUserWorkItem(delegate (object x) { result = TestMethod(); }, 4);
            //Or
            ThreadPool.QueueUserWorkItem( (object x) => { result = TestMethod(); });
            Thread.Sleep(5000);
            Console.WriteLine("Result = {0}", result);
            Console.ReadKey();
        }
        static int TestMethod()
        {            
            Console.WriteLine("TestMethod");
            return 5;
        }
    }
}

Tasks
Task is an object that represents some work that should be done. The Task can tell us if the work is completed and if the operation returns a result, the Task gives us the result.The Task scheduler uses threads from the thread pool to execute the Task.

public class myApp
{
    static bool stop = false;
    public static void Main ( )
    {
        Task t = Task.Run ( ( ) => 
        {
            while(!stop)
            {
            Console.WriteLine ( "The Task is running" );
            }
        } 
        );      
        Console.ReadKey ( );
        stop = true;
        t.Wait ( );
    }
}

Same example by creating Task explicitly, note this need to call Start() method of the Task object

class app
{
    static bool stop = false;
    public static void Main ( )
    {
        Task t = new Task ( ( ) =>
        {
            while (!stop)
            {
                Console.WriteLine ( "The Task is running" );
            }
        } );
        //Note the call of Start()
        t.Start ( );
        Console.ReadKey ( );
        stop = true;
    }
}

Another way to start the task is using StartNew method of Task Factory. Here is the modified version of previous example. Note that we don't call the Start() on Task object because StartNew () does that for us.

class app
{
    static bool stop = false;
    public static void Main ( )
    {
        Task t = Task.Factory.StartNew ( ( ) => 
        {
            while (!stop)
            {
                Console.WriteLine ( "The Task is running" );
            }
        } );
        //Note that no need to call of Start()
        Console.ReadKey ( );
        stop = true;
    }
}

We can execute the Task in separate method. We can use statement Lambda.

class app
{
    static bool stop = false;
    public static void Main ( )
    {
        Task t = Task.Factory.StartNew ( ( ) => 
        {
            while (!stop)
            {
                DoMyTask ( );
            }
        } );
        Console.ReadKey ( );
        stop = true;
    }
    public static void DoMyTask ( )
    {
        Console.WriteLine ( "Task is being executed in separate method" );
    }
}

We can execute the Task in separate method. We can use Lambda expression.

class app
{
    static bool stop = false;
    public static void Main ( )
    {
        Task t = Task.Factory.StartNew ( ( ) => DoMyTask ( ) );
        Console.ReadKey ( );
        stop = true;
    }
    public static void DoMyTask ( )
    {
        Console.WriteLine ( "Task is being executed in seperate method" );
    }
}

Note the difference between statement Lamda and Lamda expression.

x => M(x)
(x, y) => M(x, y)
(int x, int y) => M(x, y)
x => { return M(x); }
(x, y) => { return M(x, y); }
(int x, int y) => { return M(x, y); }

The first three are expression lambdas because the right hand side of the lambda operator is an expression. The last three are statement lambdas because the right hand side of the lambda operator is a block.
This also illustrates that there are three possible syntaxes for the left side: either a single parameter name, or a parenthesized list of untyped parameters, or a parenthesized list of typed parameters.

Besides Task, the .NET Framework also has the Task class that we can use if a Task should return a value.

  public static class Program
    {
        public static void Main()
        {
            Task< int>  t = Task.Run(() =>
            {
                for (int x = 0; x <  100; x++)
                {
                    Console.Write('*');
                }
                return 100;
            });
          // Wait is not necessary since we call the t. Result this block the thread till we have the result.
           t.Wait(); 
            Console.WriteLine ( "\nTask completion result = {0}", t.Result );
            Console.ReadKey ( );
        }
    }

ContinueWith previous task. Task can be chained. When a task is finished we can start new task by using the result of the previous task. See the next example.

  public static class Program
    {
        public static void Main()
        {
            Task< int>  t = Task.Run ( ( ) =>
            {
                for (int x = 0; x <  100; x++)
                {
                    Console.Write ( '*' );
                }
                return 100;
            } ).ContinueWith ( ( i ) => 
            {
                return i.Result * 3;
            } );
            t.Wait();

            Console.WriteLine ( "\nTask completion result = {0}", t.Result );
            Console.ReadKey ( );
        }
    }

Continue with overload that can handle faulted or successful situation. Conditionally task can be executed depending on some situation.

 public static class Program
    {
        public static void Main()
        {
            Task<int> t = Task.Run ( ( ) =>
            {
                for (int x = 0; x < 100; x++)
                {
                    Console.Write ( '*' );
                }
                return 100;
            } );
            
            
            
            t.ContinueWith ( ( i ) => 
            {
                Console.WriteLine ( "Canceled" );
                return i.Result * 3;
            }, TaskContinuationOptions.OnlyOnCanceled);


            t.ContinueWith ( ( i ) =>
            {
                Console.WriteLine ( "Faulted" );
                return i.Result * 3;
            }, TaskContinuationOptions.OnlyOnFaulted );


            t = t.ContinueWith ( ( i ) =>
            {
                Console.WriteLine ( "Completed" );
                return i.Result * 3;
            }, TaskContinuationOptions.OnlyOnRanToCompletion );
            t.Wait();

            Console.WriteLine ( "\nTask completion result = {0}", t.Result );
            Console.ReadKey ( );
        }
    }

Child Task: we can build a complex tasks scenario by introducing child task.
The finalTask runs only after the parent Task is finished, and the parent Task finishes when
all three children are finished.

    class program
    {
        static void Main ( )
        {
            Task<int [ ]> parent = Task.Run ( ( ) =>
            {
                var results = new int [ 3 ];
                new Task ( ( ) => { results [ 0 ] = 10; }, TaskCreationOptions.AttachedToParent ).Start ( );
                new Task ( ( ) => { results [ 1 ] = 11; }, TaskCreationOptions.AttachedToParent ).Start ( );
                new Task ( ( ) => { results [ 2 ] = 12; }, TaskCreationOptions.AttachedToParent ).Start ( );

                return results;
            } );
            var finaltask = parent.ContinueWith ( ( t ) =>
            {
                foreach (int i in t.Result)
                {
                    Console.WriteLine ( i );
                }
            } );
           // wait is not necessary since it will wait anyway 
            finaltask.Wait ( );
        }
    }

Creating task with task factory. Task factory simplified the task creation a bit easier. TaskFactory can be created with certain configuration and then the configuration can be used to create the task.


public static class Program
{
    public static void Main ( )
    {
        Task<int [ ]> parent = Task.Run ( ( ) =>
            {
                int [ ] results = new int [ 3 ];
                TaskFactory tf = new TaskFactory ( TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously );

                tf.StartNew ( ( ) => { results [ 0 ] = 10; });
                tf.StartNew ( ( ) => { results [ 1 ] = 11; } );
                tf.StartNew ( ( ) => { results [ 2 ] = 12; } );

                return results;
            } );

        var finaltask = parent.ContinueWith ( tasklist => 
        { 
            foreach(int i in tasklist.Result)
            {
                Console.WriteLine ( i ); 
            }
        } );
        finaltask.Wait ( );
        Console.ReadKey ( );
    }
}

Difference between Task Run() and Task Start():
While you use Run () then don't use Start() anymore, the task is already started by Run(). See the following code.

    class program
    {
        static void Main ( )
        {
            Task<int> t = Task.Run ( ( ) => 
            {
                return 112;
            } );
            //Get a crash when Start is called if you remove the comment
            //t.Start ( );
            t.Wait ( );
            Console.Write ( "Press a key to end " + t.Result.ToString() );
            Console.ReadKey ( );
        }
    }

Wait all for tasks, we can wait for individual task or wait for all tasks. If we run the following code we see that the code takes around 1 second though we have thread delay in 3 seconds in 3 threads. We can also wait for long running task also. Also notice that the console output is not in any order. Any task can start first, OS will decides.

    class program
    {
        static void Main ( )
        {
            Task [ ] tasks = new Task [ 3 ];
            tasks [ 0 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 1000 );
                Console.WriteLine ( "Thread 0" );
            } );

            tasks [ 1 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 1000 );
                Console.WriteLine ( "Thread 1" );
            } );
            tasks [ 2 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 1000 );
                Console.WriteLine ( "Thread 2" );
            } );

            Task.WaitAll ( tasks );
            Console.Write ( "Press a key to end " );
            Console.ReadKey ( );
        }
    }

Results of all tasks

    class program
    {
        static void Main ( )
        {

            Task <int> [ ] tasks = new Task<int> [ 3 ];

            tasks [ 0 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 3000 );
                Console.WriteLine ( "Thread 0" );
                return 111;
            } );

            tasks [ 1 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 2000 );
                Console.WriteLine ( "Thread 1" );
                return 222;
            } );
            tasks [ 2 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 1000 );
                Console.WriteLine ( "Thread 2" );
                return 333;
            } );

            Task.WaitAll ( tasks );
            Console.Write ( "Thread 1 result = {0}, Thread 2 result = {1}, Thread 3 result = {2}", tasks [ 0 ].Result, tasks [ 2 ].Result, tasks [ 2 ].Result );
            Console.ReadKey ( );
        }
    }

By using WaitAny method we can wait for any method, see also how the completed tasks are removed inside while loop.

    class program
    {
        static void Main ( )
        {
            Task <int> [ ] tasks = new Task<int> [ 3 ];
            tasks [ 0 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 3000 );
                Console.WriteLine ( "Thread 0" );
                return 111;
            } );

            tasks [ 1 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 2000 );
                Console.WriteLine ( "Thread 1" );
                return 222;
            } );
            tasks [ 2 ] = Task.Run ( ( ) =>
            {
                Thread.Sleep ( 1000 );
                Console.WriteLine ( "Thread 2" );
                return 333;
            } );
            while (tasks.Length > 0)
            {
            int i = Task.WaitAny ( tasks );
            Console.WriteLine ( "Task {0} is completed with result {1}", i, tasks [ i ].Result );
            var tasklist = tasks.ToList ( );
            tasklist.RemoveAt ( i );
            tasks = tasklist.ToArray ( );
            }
        }
    }

Cancelling a Task. By using CancellationTokenSource we can cancel a task, CancellationTokenSource
signals to a System.Threading.CancellationToken that it should be canceled. See the following example how this is used.


class app
{
    public static void Main ( )
    {
        var source = new CancellationTokenSource ( );
        try
        {
            Task t = Task.Factory.StartNew ( ( ) =>
                {
                    while(true)
                    { 
                        DoMyTask ( source.Token );
                    }
                } );
        }
        catch (Exception ex)
        {
            Console.WriteLine ( "Task cancelling exception type = {0} message = {1}", ex.GetType ( ), ex.Message );
        }

        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == 'c' || c == 'C')
            {
                if (source.IsCancellationRequested == true)
                {
                    break;
                }
                source.Cancel ( );
                Console.WriteLine ( "\nPress c or C another time to quit the app" );
            }
        }
    }
    public static void DoMyTask ( CancellationToken token )
    {
        if (token.IsCancellationRequested)
        {
            token.ThrowIfCancellationRequested ( );
            Console.WriteLine ( "Task cancel request" );            
        }
        Console.WriteLine ( "Task DoMyTask, press c or C to cancel the task" );
        Thread.Sleep ( 1000 );
    }

Parallel for and foreach:
For loop executes a for loop in which iterations may run in parallel. Below example trying to print 0 to 9 but these number will not be printed in order.

    class program
    {
        static void   Main()
        {
           // start 0 including  to 10 (excluding means till 9)
            Parallel.For ( 0, 10, ( int i ) => 
            {
                Console.WriteLine ( i );
                Thread.Sleep ( 1000 );
            } );
         
           //For each does not print all in orders
            Console.WriteLine ( " Parallel.ForEach" );
            int [ ] data =  {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
            //data can be generated by the following way
            //IEnumerable data = Enumerable.Range ( 0, 13 ); // start at 0 and count 13
            Parallel.ForEach ( data, ( int x ) => 
            {
                Console.WriteLine ( x );
                Thread.Sleep ( 1000 );
            } );

            Console.WriteLine ( "Press a key");
            Console.ReadKey ( );
        }
    }

We can cancel the loop by using the ParallelLoopState object. We have two options to do this: Break or Stop. Break ensures that all iterations that are currently running will be finished. Stop just terminates everything. See the following example.

    class program
    {
        static void   Main()
        {
            ParallelLoopResult result = Parallel.For ( 0, 2000, ( int i, ParallelLoopState loopstate ) =>
            {
                Console.WriteLine ( "Inside Thread {0}", i );
                if(i == 100)
                {
                    loopstate.Break ( );
                }
            } );

            Console.WriteLine ( "Press a key resutl = {0}", result.IsCompleted );
            Console.ReadKey ( );
        }
    }

We can use the ForAll operator to iterate over a collection when the
iteration can also be done in a parallel way. Following listing shows how to do this.

class app
{
    public static void Main ( )
    {
        var numbers = Enumerable.Range ( 0, 20 );
        var parallelResult = numbers.AsParallel ( )
            .Where ( i => i % 2 == 0 );
        parallelResult.ForAll ( ( int i ) => { Console.WriteLine ( i); } );
    }

Exception handling during parallel processing is necessary since some of the operations in parallel query throw an exception. The .NET Framework handles this by aggregating all exceptions into one AggregateException. This exception exposes a list of all exceptions that have happened during parallel
execution. Following code shows how to use it, also note that how a method can be used in where clause in parallel processing.


class app
{
    public static void Main ( )
    {
        var numbers = Enumerable.Range ( 0, 20 );
        try
        {
            var parallelResult = numbers.AsParallel ( )
                .Where ( i => IsEven ( i ) );
            parallelResult.ForAll ( e => Console.WriteLine ( e ) );
        }
        catch (AggregateException e)
        {
            Console.WriteLine ( "There where {0} exceptions", e.InnerExceptions.Count );
        }
    }

    public static bool IsEven ( int i )
    {
        if (i % 10 == 0)
        {
            throw new ArgumentException ( "i" );
        }
        return i % 2 == 0;
    }
}

Usages of await and async, see http://www.hemelix.com/async_await

Synchronization of collection:

BlockingCollection<T>
ConcurrentBag<T>
ConcurrentDictionary<TKey,T>
ConcurrentQueue<T>
ConcurrentStack<T>

BlockingCollection is shown in the following code example.
This collection is thread-safe for adding and removing data. Removing an item from the collection can be blocked until data becomes available. Adding data is fast, but you can set a maximum upper limit. If that limit is reached, adding an item blocks the calling thread until there is room.
BlockingCollection is in reality a wrapper around other collection types. If you don’t give it
any specific instructions, it uses the ConcurrentQueue by default.

class app
{
    public static void Main ( )
    {
        BlockingCollection<string> col = new BlockingCollection<string> ( );
        Task read = Task.Run ( ( ) =>
        {
            while (true)
            {
                Console.WriteLine ( "Taking = " + col.Take ( ) );
            }
        } );
        Task write = Task.Run ( ( ) =>
        {
            while (true)
            {
                string s = Console.ReadLine ( );
                if (string.IsNullOrWhiteSpace ( s )) break;
                Console.WriteLine ( "Adding = " + s );
                col.Add ( s );
            }
        } );
        write.Wait ( );
    }
}

Enumerating a ConcurrentBag. The differences between TryTake and TryPeek is that TryTake removes the object from the collection where as TryPeek just return the object without removing it.

    class program
    {
        static void Main ( )
        {
            ConcurrentBag<int> bag = new ConcurrentBag<int> ( );
            Task.Run ( ( ) =>
            {
                bag.Add ( 42 );
                bag.Add ( 22 );
                Thread.Sleep ( 1000 );
                bag.Add ( 21 );
            } );
            Task.Run ( ( ) =>
            {
                foreach (int i in bag)
                    Console.WriteLine ( i );
            } ).Wait ( );

            Console.ReadKey ( );
        }
    }

Using a ConcurrentStack
Represents a thread-safe last in-first out (LIFO) collection.

    class program
    {
        static void Main ( )
        {
            ConcurrentStack<int> stack = new ConcurrentStack<int> ( );
            stack.Push ( 23 );
            stack.Push ( 233 );

            int result;
            if(stack.TryPop(out result))
                Console.WriteLine("Popped {0}", result);

            stack.PushRange ( new int [ ] { 3, 5, 6, 9 } );

            int [] values = new int [3];
            stack.TryPopRange ( values );

            foreach (int i in values)
                Console.WriteLine ( i );

            Console.ReadKey ( );
        }
    }

ConcurrentQueue:
ConcurrentQueue offers the methods Enqueue and TryDequeue to add and remove items
from the collection. It also has a TryPeek method and it implements IEnumerable by making a
snapshot of the data. Following listing shows how to use a ConcurrentQueue.

class app
{
    public static void Main ( )
    {
        ConcurrentQueue<int> queue = new ConcurrentQueue<int> ( );
        queue.Enqueue ( 42 );
        int result;
        if (queue.TryDequeue ( out result ))
            Console.WriteLine ( "Dequeued: {0}", result );
        Console.ReadKey ( );
    }
}

ConcurrentDictionary
A ConcurrentDictionary stores key and value pairs in a thread-safe manner. We can use methods
to add and remove items, and to update items in place if they exist.

class app
{
    public static void Main ( )
    {
        var dict = new ConcurrentDictionary<string, int> ( );
        if (dict.TryAdd ( "k1", 42 ))
        {
            Console.WriteLine ( "Added" );
        }
        if (dict.TryAdd ( "k2", 41 ))
        {
            Console.WriteLine ( "Added second" );
        }
        if (dict.TryUpdate ( "k1", 21, 42 ))
        {
            Console.WriteLine ( "updated" );
        }
        dict [ "k1" ] = 42; // Overwrite unconditionally
        int r1 = dict.AddOrUpdate ( "k1", 3, ( s, i ) => i * 2 );
        int r2 = dict.GetOrAdd ( "k2", 3 );

        ICollection<int>  val = dict.Values ;
        Console.WriteLine ( "Gettings values" );
        foreach(int i in val)
        {
            Console.WriteLine ( i);
        }
        Console.ReadKey ( );
    }
}

Manage multi-threading
Multithreading problem is shown in the following example. If we run the following example then we see the value of n is different for for each run. On the other hand if the if we have the for loop limit (1000000 to 1000 for example) is small then it works fine. Why? The reason is that if the limit is small then all are executed in without context switch.


class app
{
    public static void Main ( )
    {
        int n = 0;
        var uptask = Task.Run ( ( ) =>
        {
            for (int i = 0; i < 1000000; i++)
            {
                n++;
            }
        } );

        for (int i = 0; i < 1000000; i++)
        {
            n--;
        }
        uptask.Wait ( );
        //Sounds it should be 0 but in reality it gives random value
        Console.WriteLine ( n);
        Console.ReadKey ( );
    }
}

Previous locking can be solved by using lock block. Following example shows how to use lock.

    class program
    {
        static void Main ( )
        {
            object lock_ = new object();
            int n = 0;
            var up = Task.Run ( ( ) => 
            {
                for (int i = 0; i < 1000000; i++)
                {
                    lock (lock_) 
                    {
                        n++;
                    }
                }
            } );

            for (int i = 0; i < 1000000; i++)
            {
                lock (lock_) 
                {
                    n--;
                }
            }
            up.Wait ( );
            Console.WriteLine ( n);      
            Console.ReadKey ( );
        }
    }

Lock should be private, if it public then other thread may access it. It should also be a reference type because a value type would get boxed each time we acquired a lock. In practice, this generates a completely new lock each time, losing the locking mechanism. Fortunately, the compiler helps by raising an error when you accidentally use a value type for the lock statement.

Previous code may causes the threads to block while they are waiting for each other. This can give performance problems and it could even lead to a deadlock, where both threads wait on each other, causing neither to ever complete. Following examples shows how to create deadlock. We need to be careful to avoid deadlocks in our code. We can avoid a deadlock by making sure that locks are requested in the same order. That way, the first thread can finish its work, after which the second thread can continue.
Creating a deadlock:

class app
{
    public static void Main ( )
    {
        object lockA = new object ( );
        object lockB = new object ( );

        var uptask = Task.Run ( ( ) =>
        {
            lock (lockA)
            {
                lock (lockB)
                {
                    Console.WriteLine ( "Lock  A  and  B" );
                }
            }
        } );

        lock (lockB)
        {
            //Change the value 1000 to 1 and see it does not create deadlock, why?
            Thread.Sleep ( 1000);
            lock (lockA)
            {
                Console.WriteLine ( "Lock  B  and  A" );
            }
        }
        uptask.Wait ( );
        Console.ReadKey ( );
    }
}   

Volatile class and synchronization. The out of the following code is 5. But sometimes, C# compiler optimize the code. In this case, 2 lines in Thread1 might swap the lines and thus affecting the output. To prevent this we can use volatile keyword.

class app
{
//private static volatile int _flag = 0;
    private static int _flag = 0;
    private static int _value = 0;

    public static void Thread1()
    {
        _value = 5;
        _flag = 1;
    }

    public static void Thread2 ( )
    {
        if(_flag == 1)
        {
            Console.WriteLine ( _value );
        }
    }
    public static void Main ( )
    {
        var uptask = Task.Run ( ( ) =>
        {
            Thread1 ( );
        } );

        var uptask2 = Task.Run ( ( ) =>
        {
            Thread2 ( );
        } );

        Task.WaitAll (new Task [] {uptask, uptask2} );
        Console.ReadKey ( );
    }
}

Usages of Interlocked
Interlocked guarantees that the increment and decrement operations are executed atomically.
No other thread will see any intermediate results.

class app
{
    public static void Main ( )
    {
        int n = 0;
        var up = Task.Run ( ( ) =>
        {
            for (int i = 0; i < 1000000; i++)
                Interlocked.Increment ( ref n );
        } );
        for (int i = 0; i < 1000000; i++)
            Interlocked.Decrement ( ref n );
        up.Wait ( );
        Console.WriteLine ( n );
        Console.ReadKey ( );
    }
}

Task Cancellation :
The CancellationToken is used in the asynchronous Task. The CancellationTokenSource is used to signal that the Task should cancel itself.

class app
{
    public static void Main ( )
    {
        CancellationTokenSource source = new CancellationTokenSource ( );
        CancellationToken token = source.Token;
        Task t = Task.Run ( ( ) => 
        {
            while(!token.IsCancellationRequested)
            {
                Console.Write ( "*" );
                Thread.Sleep ( 100 );
            }
        }, token );
    
        Console.WriteLine ( "Press C/c to cancel the task" );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == 'c' || c == 'C')
            {
                source.Cancel ( );
                break;
            }
        }       
        Console.WriteLine ( "Press any key to exit" );       
    }
}

How to know when a task is being cancelled? By throwing ThrowIfCancellationRequested we can know when a task is being cancelled. Following example shows how this can be done.

class app
{
    public static void Main ( )
    {
        CancellationTokenSource source = new CancellationTokenSource ( );
        CancellationToken token = source.Token;
        Task t = Task.Run ( ( ) =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.Write ( "*" );
                Thread.Sleep ( 100 );
            }
            token.ThrowIfCancellationRequested ( );
        }, token );

        Console.WriteLine ( "Press C/c to cancel the task" );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == 'c' || c == 'C')
            {
                try
                {
                    source.Cancel ( );
                }
                catch (AggregateException ex)
                {
                    Console.WriteLine ( ex.InnerExceptions [ 0 ].Message );
                }
                break;
            }
        }
        Console.WriteLine ( "Press any key to exit" );
    }
}


class app
{
    public static void Main ( )
    {
        CancellationTokenSource source = new CancellationTokenSource ( );
        CancellationToken token = source.Token;
        Task t = Task.Run ( ( ) =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.Write ( "*" );
                Thread.Sleep ( 100 );
            }
            token.ThrowIfCancellationRequested ( );
        }, token ).ContinueWith ( ( task) =>
        {
            task.Exception.Handle ( ( e ) => true );
            Console.WriteLine ( "Task has been Cancelled" );
        }, TaskContinuationOptions.OnlyOnCanceled );

        Console.WriteLine ( "Press C/c to cancel the task" );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == 'c' || c == 'C')
            {
                try
                {
                    source.Cancel ( );
                }
                catch (AggregateException ex)
                {
                    Console.WriteLine ( ex.InnerExceptions [ 0 ].Message );
                }
                break;
            }
        }
        Console.WriteLine ( "Press any key to exit" );
    }
}

Instead of catching the exception, we can also add a continuation Task that executes only when the Task is canceled. In this Task, we can have access to the exception that was thrown, and you can choose to handle it if that’s appropriate.

class app
{
    public static void Main ( )
    {
        CancellationTokenSource source = new CancellationTokenSource ( );
        CancellationToken token = source.Token;
        Task t = Task.Run ( ( ) =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.Write ( "*" );
                Thread.Sleep ( 100 );
            }
            token.ThrowIfCancellationRequested ( );
        }, token ).ContinueWith ( ( task) =>
        {
            task.Exception.Handle ( ( e ) => true );
            Console.WriteLine ( "Task has been Cancelled" );
        }, TaskContinuationOptions.OnlyOnCanceled );

        Console.WriteLine ( "Press C/c to cancel the task" );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == 'c' || c == 'C')
            {
                try
                {
                    source.Cancel ( );
                }
                catch (AggregateException ex)
                {
                    Console.WriteLine ( ex.InnerExceptions [ 0 ].Message );
                }
                break;
            }
        }
        Console.WriteLine ( "Press any key to exit" );
    }
}

Cancelling a task based on timeout:
If we want to cancel a Task after a certain amount of time, we can use an overload of Task.WaitAny that takes a timeout, following example shows it. If ThreadSleepTime is greater that TaskTimeOutTime then we get the return value of WaitAny() as -1. On the other hand if the ThreadSleepTime less than the TaskTimeOutTime then it will be 0 (Task will be completed before the time out ).

class app
{
    //Thread will sleep 10 seconds
    static int ThreadSleepTime = 10000;
    //Thread will be cancelled after 2 seconds
    static int TaskTimeOutTime = 2000;
    public static void Main ( )
    {
        Task longRunning = Task.Run ( ( ) =>
        {
                Console.WriteLine ( "Task is running" );
                Thread.Sleep ( 10000 );
        } );

        int index = Task.WaitAny ( new [] {longRunning}, 2000 );
        Console.WriteLine ( "Task returns {0}", index );
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == 'c' || c == 'C')
            {
                break;
            }
        }
        Console.WriteLine ( "Press any key to exit" );
    }
}

Passing parameters to calling methods

    class program
    {
        static void Main ( )
        {
            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == 'c' || c == 'C')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
                switch(c)
                {
                    case '1':
                    {
                        TestMethod ( 10 );
                    }
                    break;

                    case '2':
                    {
                        TestMethod ( 10, "Second Parameter" );
                    }
                    break;

                    case '3':
                    {
                        TestMethod ( 10, "Second Parameter", true );
                    }
                    break;

                    case '4':
                    {
                        //Using 2nd as default  and third as custom value
                        //Since we are ommiting 2nd parameter we need to pass like thridDefaultFalse:true
                        TestMethod ( 10, thridDefaultFalse:true );
                    }
                    break;

                    default:
                    {

                    }
                    break;

                }
            }
            Console.ReadKey ( );
        }
        public static void TestMethod(int firstArgument, string secondArgument = "Second Devault Value",  bool thridDefaultFalse = false)
        {
            Console.WriteLine ( "\nfirstArgument = {0}, secondArgument = {1}, ThirdArgument = {2}", firstArgument, secondArgument, thridDefaultFalse );
        }
    }

Function Overloading

    class program
    {
        static void Main ( )
        {

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == 'c' || c == 'C')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
                switch(c)
                {
                    case '1':
                    {
                        TestMethod ( 10 );
                    }
                    break;

                    case '2':
                    {
                        TestMethod ( 10, "Second Parameter" );
                    }
                    break;

                    case '3':
                    {
                        TestMethod ( 10, "Second Parameter", true );
                    }
                    break;

                    case '4':
                    {
                        //Using 2nd as default  and third as custom value
                        //Since we are ommiting 2nd parameter we need to pass like thridDefaultFalse:true
                        TestMethod ( 10, thridDefaultFalse:true );
                    }
                    break;

                    case '5':
                    {
                        TestMethod ( 30, 10, "Second Parameter", true );
                    }
                    break;

                    default:
                    {

                    }
                    break;

                }
            }
            Console.ReadKey ( );
        }

        public static void TestMethod(int firstArgument, string secondArgument = "Second Devault Value",  bool thridDefaultFalse = false)
        {
            Console.WriteLine ( "\nfirstArgument = {0}, secondArgument = {1}, ThirdArgument = {2}", firstArgument, secondArgument, thridDefaultFalse );
        }

        public static int TestMethod ( int b, int firstArgument, string secondArgument = "Second Devault Value", bool thridDefaultFalse = false )
        {
            Console.WriteLine ( "\nfirstArgument = {0}, secondArgument = {1}, ThirdArgument = {2}", firstArgument, secondArgument, thridDefaultFalse );
            Console.WriteLine ( b );
            return 0;
        }
    }

Creating class, note how the default constructor is called

     class Card 
    {
         private int x;
         public Card ( ) { this.x = 3; }
         //public Card ( ) : this ( 3 ) { }
         public Card(int p)
         {
             this.x = p;
         }
    }

Extension Method

    

class Product
    {
        public decimal Price { get; set; }
    }

     static class  ProdctExtensions
    {
        public  static decimal Discount(this Product product)
        {
            return product.Price * .9M;
        }
    }

    class program
    {
        static void Main ( )
        {

            Product p = new Product ( );
            p.Price = 200;

            decimal dm = p.Discount ( );
            Console.WriteLine ( dm );

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == 'c' || c == 'C')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
            Console.ReadKey ( );
        }
    }

//XML Reading and Writing

    class program
    {
        static void Main ( )
        {
            double cost = 1234.56;
            Console.WriteLine ( cost.ToString ( "C", new CultureInfo ( "en-US" ) ) );

            var stringWriter = new StringWriter ( );
            using (XmlWriter writer = XmlWriter.Create ( stringWriter ))
            {
                writer.WriteStartElement ( "book" );
                writer.WriteElementString ( "price", "19.95" );
                writer.WriteEndElement ( );
                writer.Flush ( );
            }
            string xml = stringWriter.ToString ( );
            Console.WriteLine ( xml );

            var stringReader = new StringReader ( xml );
            using(XmlReader  reader = XmlReader.Create(stringReader))
            {
                reader.ReadToFollowing ( "price" );
                decimal price = decimal.Parse ( reader.ReadInnerXml ( ), new CultureInfo ( "en-US" ) );
            }

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }
    }

//Encryption

    class program
    {
        static void Main ( )
        {


            EncryptSomeText ( );


            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }



        public static void EncryptSomeText ( )
        {
            string original = "My secret data!";
            using (SymmetricAlgorithm symmetricAlgorithm = new AesManaged ( ))
            {
                byte [ ] encrypted = Encrypt ( symmetricAlgorithm, original );
                string roundtrip = Decrypt ( symmetricAlgorithm, encrypted );
                // Displays: My secret data! 
                Console.WriteLine ( "Original:   {0}", original );
                Console.WriteLine ( "Round Trip: {0}", roundtrip );
            }
        }
        static byte [ ] Encrypt ( SymmetricAlgorithm aesAlg, string plainText )
        {
            ICryptoTransform encryptor = aesAlg.CreateEncryptor ( aesAlg.Key, aesAlg.IV );
            using (MemoryStream msEncrypt = new MemoryStream ( ))
            {
                using (CryptoStream csEncrypt = new CryptoStream ( msEncrypt, encryptor, CryptoStreamMode.Write ))
                {
                    using (StreamWriter swEncrypt = new StreamWriter ( csEncrypt ))
                    {
                        swEncrypt.Write ( plainText );
                    }
                    return msEncrypt.ToArray ( );
                }
            }
        }

        static string Decrypt ( SymmetricAlgorithm aesAlg, byte [ ] cipherText )
        {
            ICryptoTransform decryptor = aesAlg.CreateDecryptor ( aesAlg.Key, aesAlg.IV );
            using (MemoryStream msDecrypt = new MemoryStream ( cipherText ))
            {
                using (CryptoStream csDecrypt = new CryptoStream ( msDecrypt, decryptor, CryptoStreamMode.Read ))
                {
                    using (StreamReader srDecrypt = new StreamReader ( csDecrypt ))
                    {
                        return srDecrypt.ReadToEnd ( );
                    }

                }
            }
        }
    }

//Timer, passed object to callback and demo of GC (Check release mode and debug mode)

    class program
    {
        static void Main ( )
        {
            int i = 400;
            Timer t = new Timer ( TimerCallback, i, 0, 2000 );

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }

        private static void TimerCallback ( Object o )
        {            
            Console.WriteLine ( "In TimerCallback: {0} and passed data {1}" , DateTime.Now, (int)o );
            GC.Collect ( ); // For release mode GC remove the object and timer is not fired anymore.
        }
    }

// Stream and compression, decorator pattern

    class program
    {
        static void Main ( )
        {
            string folder = @"C:\temp";
            string uncompressedfilepath = Path.Combine ( folder, "uncompressed.dat" );
            string compressedfilepath = Path.Combine ( folder, "compressed.gz" );
            byte [ ] datatocompress = Enumerable.Repeat ( (byte)'a', 1024 * 1024 ).ToArray ( );

            using (FileStream uncompressedfileStream = File.Create ( uncompressedfilepath ))
            {
                uncompressedfileStream.Write ( datatocompress, 0, datatocompress.Length );
            }

            using (FileStream compressedFileStream = File.Create ( compressedfilepath ))
            {
                using (GZipStream compressionStream = new GZipStream (compressedFileStream, CompressionMode.Compress ))
                {
                    compressionStream.Write ( datatocompress, 0, datatocompress.Length );
                }
            }


            FileInfo uncompressedFile = new FileInfo ( uncompressedfilepath );
            FileInfo compressedFile = new FileInfo ( compressedfilepath );
            Console.WriteLine ( uncompressedFile.Length ); // Displays 1048576
            Console.WriteLine ( compressedFile.Length ); // Displays 1052


            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }
    }

//XML Serializer

    [Serializable]
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }

    class program
    {
        static void Main ( )
        {
            XmlSerializer serializer = new XmlSerializer ( typeof ( Person ) );
            string xml;
            using (StringWriter stringWriter = new StringWriter ( ))
            {
                Person p = new Person
                {
                    FirstName = "John",
                    LastName = "Doe",
                    Age = 42
                };
                serializer.Serialize ( stringWriter, p );
                xml = stringWriter.ToString ( );
            }
            Console.WriteLine ( xml );
            using (StringReader stringReader = new StringReader ( xml ))
            {
                Person p = (Person)serializer.Deserialize ( stringReader );
                Console.WriteLine ( "{0} {1} is {2} years old", p.FirstName, p.LastName, p.Age );
            }

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }
    }

//Binary Formatter

    [Serializable]
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        private bool isDirty = false;
    }

    class program
    {
        static void Main ( )
        {

            Person p = new Person
                {
                    Id = 1,
                    Name = "John Doe"
                };

            IFormatter formatter = new BinaryFormatter ( );
            using (Stream stream = new FileStream ( "data.bin", FileMode.Create ))
            {
                formatter.Serialize ( stream, p );
            }
            using (Stream stream = new FileStream ( "data.bin", FileMode.Open ))
            {
                Person dp = (Person)formatter.Deserialize ( stream );
            }

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }
    }

// Serializable class

    [Serializable]
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        private bool isDirty = false;
    }

    class program
    {
        static void Main ( )
        {

            Person p = new Person
                {
                    Id = 1,
                    Name = "John Doe"
                };

            IFormatter formatter = new BinaryFormatter ( );
            using (Stream stream = new FileStream ( "data.bin", FileMode.Create ))
            {
                formatter.Serialize ( stream, p );
            }
            using (Stream stream = new FileStream ( "data.bin", FileMode.Open ))
            {
                Person dp = (Person)formatter.Deserialize ( stream );
            }

            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }
    }

// Inheritance, use of is, as and array of objects, cast

    class Person
    {
        public int MyProperty { get; set; }
        public void PersonMethod()
        {
            Console.WriteLine ( "Person method called" );
        }
    }


    class Employee : Person
    {
        public int MyProperty { get; set; }
        public int id;
        public Employee(int i)
        {
            this.id = i;
        }
        public void EmployeeMethod ( )
        {
            Console.WriteLine ( "Employee method called" );
        }
    }

    class Manager : Employee
    {
        public int MyProperty { get; set; }

        public Manager(int id): base(id)
        {

        }
        public void ManagerMethod ( )
        {
            Console.WriteLine ( "Manager method called" );
        }
    }

    class program
    {

        static Person mPerson;
        static Employee mEmployee;
        static Manager mManager;




        static void Main ( )
        {

            Employee [ ] employees = new Employee [ 10 ];
            for(int id = 0; id < employees.Length; id++)
            {
                employees [ id ] = new Employee ( id + 1 );
            }

            Person [ ] mypersons = employees;
            Employee [ ] myemployeelist = (Employee [])mypersons;



            while (true)
            {
                char c = Console.ReadKey ( ).KeyChar;
                if (c == ' ')
                {
                    Console.WriteLine ( "\nExiting app..." );
                    break;
                }
            }
        }
    }
 

GetInvocationList gives us the total number of methods in the invocation list. Following list shows how many methods are in the list.

class app
{
    public delegate void MyDelegate ( );
    public static void Main ( )
    {
        MyDelegate del = new MyDelegate ( MethodOne );
        del += MethodTwo;
        del ( );
        int invocationCount = del.GetInvocationList ( ).GetLength ( 0 );
        Console.WriteLine ( "invocationCount = {0}", invocationCount ); //Print 2
        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                break;
            }
        }
    }

    public static void MethodOne ( )
    {
        Console.WriteLine ( "MethodOne" );
    }

    public static void MethodTwo ( )
    {
        Console.WriteLine ( "MethodTwo" );
    }
}

Most cases we must follow the signature and return type of delegate. But this is not the case with covariance and contravariance. Covariance makes it possible that a method has a return type that is more derived than that defined in the delegate. Contravariance permits a method that has parameter types that are less derived than those in the delegate type.

class Human
{
    public int FirstName { get; set; }
}

class Student : Human
{
    public int LastName { get; set; }
}
class app
{
    public delegate Human MyDelegate ( Student human );
    public static void Main ( )
    {
        MyDelegate del = new MyDelegate ( MethodOne );
        del += MethodTwo;
        Student s = new Student();
        del ( s);

        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                break;
            }
        }
    }

    public static Student MethodOne (Human s )
    {
        Student st = new Student ( );
        Console.WriteLine ( "MethodOne" );
        return st;
    }

    public static Student MethodTwo ( Human s)
    {
        Student st = new Student ( );
        Console.WriteLine ( "MethodTwo" );
        return st;
    }
}

Try catch and finally

///
//  hide.cs - 
//--------------------------------------------------------------------

using System;
using System.Collections;


public class myApp
{


    public static void Main ( )
    {

        Console.WriteLine ( "Insert something and then press enter:" );
        string s = null;
        int number = 0;

        while (true)
        {
            s = Console.ReadLine ( );
            try
            {
                Console.WriteLine ( "Inside try block" );
                number = int.Parse ( s );
                Console.WriteLine ( "Number inserted {0}", number );
                
            }
            catch (ArgumentNullException ex)
            {
                Console.WriteLine ( "ArgumentNullException message = " + ex.Message );
            }
            catch (OverflowException ex)
            {
                Console.WriteLine ( "OverflowException message = " + ex.Message );
            }
            catch (FormatException ex)
            {
                Console.WriteLine ( "FormatException message = " + ex.Message );
            }
            catch (Exception ex)
            {
                Console.WriteLine ( "Exception message = " + ex.Message );
            }
            finally
            {
                Console.WriteLine ( "Finally block" );
            }

            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                Console.WriteLine ( "\nExiting app..." );
                break;
            }
            Console.Clear ( );
        }
    }
}

//Stop watch
// Stopwatch is defined in System (in System.dll) Assemblies,
// Check if System.dll is included in References (If not added it can be added by right clicking on references in solution explorer )
// Add the namespace  using System.Diagnostics;
// See https://msdn.microsoft.com/en-us/library/System.Diagnostics.Stopwatch(v=vs.110).aspx

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace StopWatchTest
{
    class Program
    {
        static void Main ( string [ ] args )
        {

            Stopwatch stopWatch = new Stopwatch ( );
            stopWatch.Start ( );
            Thread.Sleep ( 10000 );
            stopWatch.Stop ( );
            // Get the elapsed time as a TimeSpan value.
            TimeSpan ts = stopWatch.Elapsed;

            // Format and display the TimeSpan value. 
            string elapsedTime = String.Format ( "{0:00}:{1:00}:{2:00}.{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds / 10 );
            Console.WriteLine ( "RunTime " + elapsedTime );
        }
    }
}

// Time calculation between main thread and threadpool thread
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace StopWatchTest
{

    class Program
    {
        static void Main ( string [ ] args )
        {
            // We are using Stopwatch to time the code
            Stopwatch sw = Stopwatch.StartNew ( );
            // Here we call different methods
            // for different ways of running our application.
            RunSequencial ( );
            // Print the time it took to run the application.
            Console.WriteLine ( "We're done in {0}ms!", sw.ElapsedMilliseconds );
            if (Debugger.IsAttached)
            {
                Console.Write ( "Press any key to continue . . ." );
                Console.ReadKey ( true );
            }
        }
        static void RunSequencial ( )
        {
            double result = 0d;

            ThreadPool.QueueUserWorkItem (
                ( object x ) =>
                {
                    result += ReadDataFromIO ( );
                    Console.WriteLine ( "Thread pool thread done {0}", result );
                }
            );

            // Call the function to read data from I/O
            // result += ReadDataFromIO ( );
            // Add the result of the second calculation
            result += DoIntensiveCalculations ( );
            Console.WriteLine ( "Intensive work thread done {0}", result );

            // Print the result
            Console.WriteLine ( "Final The result is {0}", result );
        }
        static double ReadDataFromIO ( )
        {
            // We are simulating an I/O by putting the current thread to sleep.
            Thread.Sleep ( 0 );
            return 10d;
        }
        static double DoIntensiveCalculations ( )
        {
            // We are simulating intensive calculations
            // by doing nonsens divisions
            double result = 0.0d;
            var maxValue = Int32.MaxValue;
            for (int i = 1; i < maxValue; i++)
            {
                result /= i;
            }
            return result + 10d;
        }
    }
}
//ArrayList  and sorting 
//  hide.cs - 
//--------------------------------------------------------------------

using System;
using System.Collections;
using System.Diagnostics;
using System.Threading;


public class myApp
{

    class MyObject : IComparable
    {
        public int ID { get; set; }

        public int CompareTo ( object obj )
        {
            MyObject obj1 = obj as MyObject;
            return this.ID.CompareTo ( obj1.ID );
        }
    }

    public static void Main ( )
    {
        ArrayList myList = new ArrayList ( );
        myList.Add ( new MyObject ( ) { ID = 3 } );
        myList.Add ( new MyObject ( ) { ID = 4 } );
        myList.Add ( new MyObject ( ) { ID = 1 } );
        myList.Add ( new MyObject ( ) { ID = 5 } );
        myList.Add ( new MyObject ( ) { ID = 3 } );
        myList.Add ( new MyObject ( ) { ID = 3 } );
        myList.Add ( new MyObject ( ) { ID = 2 } );
        myList.Sort ( );
        int foundIndex = myList.BinarySearch ( new MyObject ( ) { ID = 47 } );
        if (foundIndex >= 0)
        {
            Console.WriteLine ( ((MyObject)myList [ foundIndex ]).ID.ToString ( ) );
        }
        else
        {
            Console.WriteLine ( "Element not found" );
        }
        while (true)
        {            
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                Console.WriteLine ( "\nExiting app..." );
                break;
            }
        }
    }
}

Array to List and List to array.
Following section explain how we can convert array to string list and vice versa.

namespace Chapter1.Threads
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create a List of integer and initialize
            List myintlist = new List { 1, 2, 3, 4, 5};
          
           //Add a value at the end
            myintlist.Add(20);
    
           //Iterate  the list
            foreach(int i in myintlist)
            {
                Console.WriteLine(i);
            }
           
            //Make an array of integer
            int[] myintarray = myintlist.ToArray();

           //Make list back
            List newlist = myintarray.ToList();

       //Iterate  the list
            foreach (int i in newlist)
            {
                Console.WriteLine(i);
            }
            Console.WriteLine("Getting via IEnumerator");

            IEnumerator en = newlist.GetEnumerator();
            while(en.MoveNext())
            {
                Console.WriteLine(en.Current);
            }

            Console.ReadKey();
        }
    }
}
// LINQ creating anonymous object from another object.
using System;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Xml.Serialization;

public class myApp
{
    class Hometown
    {
        public string City { get; set; }
        public int ID { get; set; }
    }

    public static void Main ( )
    {
        List myList = new List ( );
        Hometown town1 = new Hometown ( ) { City = "A", ID = 1 };
        myList.Add ( town1);
        Hometown town2 = new Hometown ( ) { City = "B", ID = 2 };
        myList.Add ( town2 );
        Hometown town3 = new Hometown ( ) { City = "C", ID = 3 };
        myList.Add ( town3 );
        Hometown town4 = new Hometown ( ) { City = "D", ID = 4 };
        myList.Add ( town4);

        var mylist = from i in myList
                     select new { Amount = i.ID, Message = i.City};

        foreach (var data in mylist)
        {
            Console.WriteLine ( data.Amount);
            Console.WriteLine ( data.Message );
        }

        while (true)
        {
            char c = Console.ReadKey ( ).KeyChar;
            if (c == ' ')
            {
                Console.WriteLine ( "\nExiting app..." );
                break;
            }
        }
    }

}

This site is updated and maintained by Mahbub Rahman.
Updated on 07/20/2015
if you want to contribute or comment please contact me.