Saturday, May 21, 2011

Threading

Threading enables your Visual Basic or C# program to perform concurrent processing so that you can do more than one operation at a time. For example, you can use threading to monitor input from the user, perform background tasks, and handle simultaneous streams of input.
Threads have the following properties:
  • Threads enable your program to perform concurrent processing.
  • The .NET Framework System.Threading namespace makes using threads easier.
  • Threads share the application's resources. For more information, see Using Threads and Threading.
By default, a Visual Basic or C# program has one thread. However, auxiliary threads can be created and used to execute code in parallel with the primary thread. These threads are often called worker threads.

Example :


namespace ConsoleApplication1
{
    public class ServerClass
    {
        // The method that will be called when the thread is started.
        public void InstanceMethod()
        {
            Console.WriteLine(
                "ServerClass.InstanceMethod is running on another thread." + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());


            int x =0;
            for (int i = 0; i < 1000000000; i++)
            {
                x += x;
            }


            // Pause for a moment to provide a delay to make
            // threads more apparent.
            //Thread.Sleep(3000);
            //Thread.CurrentThread.Abort();
            Console.WriteLine(
                "The instance method called by the worker thread has ended. " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        }


        
    }


    public class Simple
    {
        
        public static void Main()
        {
            Console.WriteLine("Thread Simple Sample");
            DateTime datetime = System.DateTime.Now;
            long elapsedTicks = System.DateTime.Now.Ticks - datetime.Ticks;
            Console.WriteLine(elapsedTicks.ToString());
            for (int i = 0; i < 2; i++)
            {


                ServerClass serverObject = new ServerClass();
                Thread InstanceCaller = new Thread(
                    new ThreadStart(serverObject.InstanceMethod));


                // Start the thread.
                InstanceCaller.Start();


                Console.WriteLine("The Main() thread calls this after "
                    + "starting the new InstanceCaller thread.");
           
            }
            elapsedTicks = System.DateTime.Now.Ticks - datetime.Ticks;
            Console.WriteLine(elapsedTicks.ToString());
            Console.ReadLine();
        }
    }


}


thread pool is a collection of threads that can be used to perform several tasks in the background. This leaves the primary thread free to perform other tasks asynchronously.



 System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(AnotherLongTask));
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);

Friday, May 20, 2011

Reflection in C#

Reflection is the ability of a managed code to read its own metadata for the purpose of finding assemblies, modules and type information at runtime. In other words, reflection provides objects that encapsulate assemblies, modules and types.


namespace ReflectionLibrary
{
    public class MyClass
    {
        public virtual string AddNumb(int numb1, string numb2)
        {
            string result = numb1.ToString() + numb2;
            return result;
        }


    }
}


using System.Reflection;
using ReflectionLibrary;
namespace ConsoleApplication1
{
    class MyMainClass
    {
        public static int Main()
        {
            // Create MyClass object
            MyClass myClassObj = new MyClass();
            // Get the Type information.
            //Type myTypeObj = myClassObj.GetType();
            // Get Method Information.
            MethodInfo myMethodInfo = myClassObj.GetType().GetMethod("AddNumb");
            object[] mParam = new object[] { 5, "Vivek" };
            // Get and display the Invoke method.
            Console.WriteLine(myMethodInfo.Invoke(myClassObj, mParam));
            Console.ReadLine();
            return 0;
        }
    }
}



Wednesday, May 18, 2011

Properties vs. Public Variables

I occasionally see code with properties like this:
private int name;
public int Name{
    
get { return name; }
    
set { name = value; }
}


Why waste everyone's time with a bunch of meaningless just-in-case wrapper code? Start with the simplest thing that works-- a public variable. You can always refactor this later into a property if it turns out additional work needs to be done when the name value is set. If you truly need a property, then use a property. Otherwise, KISS!
Update: As many commenters have pointed out, there are valid reasons to make a trivial property, exactly as depicted above:
  • Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
  • You can't databind against a variable.
  • Changing a variable to a property is a breaking change.
It's a shame there's so much meaningless friction between variables and properties; most of the time they do the exact same thing. Kevin Dente proposed a bit of new syntax that would give us the best of both worlds:
public property int Name;
The really important thing to take away here is to avoid writing code that doesn't matter. And property wrappers around public variables are the very essence of meaningless code.

Saturday, May 14, 2011

Multicast Delegates


There are three steps in defining and using delegates: declaration, instantiation, and invocation.
multi-cast delegate is basically a list of delegates or a list of methods with the same signature. A multi-cast delegate can call a collection of methods instead of only a single method.

Remarks

.Net delegates are all multi-cast delegates. When calling a multi-cast delegate that returns a value, only the last value will be returned. In order to process every return value, iterate the delegate list and invoke each delegate individually.
If one of the methods throws an exception, the delegate call will immediately stop and no other methods in the list will be called.
// Declaration
public delegate void VerySimpleDelegate();

class TestDelegate
{
    public static void Foo()
    {
        Console.WriteLine("Foo was called by a delegate!");
    }

    public static void Bar()
    {
        Console.WriteLine("Bar was called by a delegate!");
    }

    public static void Main()
    {
        // Instantiation
        VerySimpleDelegate vsd = new VerySimpleDelegate(Foo);  //#1

        // Invocation
        vsd();

        //Another Instantiation
        vsd = Bar;
        vsd();
    }
}
What do you notice when you run the application? Yes, you are right... you are not calling the functions Foo and Bar directly! Instead, you are creating a delegate (#1). Also notice, you just assigned vsd = Bar, which was another function name. Calling vsd again in the next line called the function called Bar as you can see in the output below!!! image Thus, to use delegate you need to use the following approach... (check the comments in code snipped above to find the following)
    Declaration     Instantiation     Invocation
May be you are thinking, why all this headache? What is the need to do all this? Reason 1> You have to call different functions based on some dynamic requirement but you don't want your function calls to change. In our previous code snipped vsd() doesn't change, although the actual function that it is referring to has changed altogether. Let's take a look at another sample... Example2
public class Example2
{
    // Declaration - Take 1 parameter, return nothing
    public delegate void LogHandler(string message);

    // Instantiation - Create a function which takes delegate as one parameter
    // Verify if it is null before you use it
    public void Process(LogHandler logHandler)
    {
        if (logHandler != null)
        {
            logHandler("Process() begin");
        }

        if (logHandler != null)
        {
            logHandler("Process() end");
        }
    }
}

public class Example2DelegateConsumer
{
    // Create a method with the same signature as the delegate
    static void Logger(string s)
    {
        Console.WriteLine(s);
    }

    public static void Main(string[] args)
    {
        Example2 ex2 = new Example2();

        // Invocation in the client
        Example2.LogHandler myLogger = new Example2.LogHandler(Logger);
        ex2.Process(myLogger);
    }
}
Reason 2> As you can see above, you can use delegates to call static functions. In our case, the function Logger with a parameter was being called by Process function in the Example2 class. This approach is called Callback.
    public class Example3
    {
        // Declaration - Take 1 parameter, return nothing
        public delegate void LogHandler(string message);

        // Instantiation - Create a function which takes delegate as one parameter
        // Verify if it is null before you use it
        public void Process(LogHandler logHandler)
        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler("Process() end");
            }
        }
    }

    public class FileLogger
    {
        FileStream fs;
        StreamWriter sw;

        // Constructor
        public FileLogger(string filename)
        {
            fs = new FileStream(filename, FileMode.Create);
            sw = new StreamWriter(fs);
        }

        // Create a method with the same signature as the delegate
        public void Logger(string s)
        {
            sw.WriteLine(s);
        }

        public void Close()
        {
            sw.Close();
            fs.Close();
        }
    }

    public class Example3DelegateConsumer
    {
        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger("C:\\Labfiles\\process.log");
            Example3 ex3 = new Example3();
            
            // Invocation in the client
            // Notice that now instead of Logger function, we are passing fl.Logger function.
            Example3.LogHandler myLogger = new Example3.LogHandler(fl.Logger);
            ex3.Process(myLogger);
            fl.Close();
        }
    }
Reason 3> Without changing the Example3 delegate, we were able to change the location where a log needs to be written. In the previous example, you would have noticed that we had a Logger function in the same class. Now, we know we can point to any function with the same signature as a delegate from a different class as well. In our example we called the function from the class FileLogger. The key here is that the Logger function is not in the Example3DelegateConsumer class!!! What if you want to display the results, and write them at the same time??
namespace Delegates4
{
    public class Example4
    {
        // Declaration - Take 1 parameter, return nothing
        public delegate void LogHandler(string message);

        // Instantiation - Create a function which takes delegate as one parameter
        // Verify if it is null before you use it
        public void Process(LogHandler logHandler)
        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler("Process() end");
            }
        }
    }

    public class FileLogger
    {
        FileStream fs;
        StreamWriter sw;

        // Constructor
        public FileLogger(string filename)
        {
            fs = new FileStream(filename, FileMode.Create);
            sw = new StreamWriter(fs);
        }

        // Create a method with the same signature as the delegate
        public void Logger(string s)
        {
            sw.WriteLine(s);
        }

        public void Close()
        {
            sw.Close();
            fs.Close();
        }
    }

    public class Example4DelegateConsumer
    {
        // Create a method with the same signature as the delegate
        static void Logger(string s)
        {
            Console.WriteLine(s);
        }
        
        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger("C:\\Labfiles\\process.log");
            Example4 ex4 = new Example4();

            // Invocation in the client
            // Notice that now instead of Logger function, we are passing fl.Logger function
            // along with another Logger which is defined in the same class
            Example4.LogHandler myLogger = null;
            myLogger += new Example4.LogHandler(Logger);
            myLogger += new Example4.LogHandler(fl.Logger);
            ex4.Process(myLogger);
            fl.Close();
        }
    }
}
Reason 4> As you can see above, we have registered two methods for the same delegate. This is what is typically mentioned as Multicast delegate.  By default in C#, delegates are multicast. I hope this clarifies the basic concepts of delegates, and why you would use them in the first place. In the next post, I will tell you about how to use delegates for events.  Stay tuned!

Another example : 
delegate void Del(string s);

class TestClass
{
    static void Hello(string s)
    {
        System.Console.WriteLine("  Hello, {0}!", s);
    }

    static void Goodbye(string s)
    {
        System.Console.WriteLine("  Goodbye, {0}!", s);
    }

    static void Main()
    {
        Del a, b, c, d;

        // Create the delegate object a that references 
        // the method Hello:
        a = Hello;

        // Create the delegate object b that references 
        // the method Goodbye:
        b = Goodbye;

        // The two delegates, a and b, are composed to form c: 
        c = a + b;

        // Remove a from the composed delegate, leaving d, 
        // which calls only the method Goodbye:
        d = c - a;

        System.Console.WriteLine("Invoking delegate a:");
        a("A");
        System.Console.WriteLine("Invoking delegate b:");
        b("B");
        System.Console.WriteLine("Invoking delegate c:");
        c("C");
        System.Console.WriteLine("Invoking delegate d:");
        d("D");
    }
}
/* Output:
Invoking delegate a:
  Hello, A!
Invoking delegate b:
  Goodbye, B!
Invoking delegate c:
  Hello, C!
  Goodbye, C!
Invoking delegate d:
  Goodbye, D!
*/

Delegates and Events in C# / .NET

Content


Overview

All of us have been exposed to event driven programming of some sort or the other. C# adds on value to the often mentioned world of event driven programming by adding support through events and delegates. The emphasis of this article would be to identify what exactly happens when you add an event handler to your common UI controls. A simple simulation of what could possibly be going on behind the scenes when the AddOnClick or any similar event is added to the Button class will be explained. This will help you understand better the nature of event handling using multi cast delegates.

Delegates

A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.
In most cases, when we call a function, we specify the function to be called directly. If the class MyClass has a function named Process, we'd normally call it like this (SimpleSample.cs):
using System;

namespace Akadia.NoDelegate
{
    public class MyClass
    {
        public void Process()
        {
            Console.WriteLine("Process() begin");
            Console.WriteLine("Process() end");
        }
    }

    public class Test
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            myClass.Process();
        }
    }
}
That works well in most situations. Sometimes, however, we don't want to call a function directly - we'd like to be able to pass it to somebody else so that they can call it. This is especially useful in an event-driven system such as a graphical user interface, when I want some code to be executed when the user clicks on a button, or when I want to log some information but can't specify how it is logged.
An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references. Any object will do; all that matters is that the method's argument types and return type match the delegate's. This makes delegates perfectly suited for "anonymous" invocation.
The signature of a single cast delegate is shown below:
delegate result-type identifier ([parameters]);
where:
  • result-type: The result type, which matches the return type of the function.
  • identifier: The delegate name.
  • parameters: The Parameters, that the function takes.
Examples:
public delegate void SimpleDelegate ()
This declaration defines a delegate named SimpleDelegate, which will encapsulate any method that takes
no parameters and returns no value.
public delegate int ButtonClickHandler (object obj1, object obj2)
This declaration defines a delegate named ButtonClickHandler, which will encapsulate any method that takes
two objects as parameters and returns an int.
A delegate will allow us to specify what the function we'll be calling looks like without having to specify whichfunction to call. The declaration for a delegate looks just like the declaration for a function, except that in this case, we're declaring the signature of functions that this delegate can reference.
There are three steps in defining and using delegates:
  • Declaration
  • Instantiation
  • Invocation
A very basic example (SimpleDelegate1.cs):
using System;

namespace Akadia.BasicDelegate
{
    // Declaration
    public delegate void SimpleDelegate();

    class TestDelegate
    {
        public static void MyFunc()
        {
            Console.WriteLine("I was called by delegate ...");
        }

        public static void Main()
        {
            // Instantiation
            SimpleDelegate simpleDelegate = new SimpleDelegate(MyFunc);

            // Invocation
            simpleDelegate();
        }
    }
}
Compile an test:
# csc SimpleDelegate1.cs
# SimpleDelegate1.exe
I was called by delegate ...
For our next, more advanced example (SimpleDelegate2.cs), declares a delegate that takes a single string parameter and has no return type:
using System;

namespace Akadia.SimpleDelegate
{
    // Delegate Specification
    public class MyClass
    {
        // Declare a delegate that takes a single string parameter
        // and has no return type.

        public delegate void LogHandler(string message);
        // The use of the delegate is just like calling a function directly,
        // though we need to add a check to see if the delegate is null
        // (that is, not pointing to a function) before calling the function.

        public void Process(LogHandler logHandler)
        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler ("Process() end");
            }
        }
    }

    // Test Application to use the defined Delegate
    public class TestApplication
    {
       
 // Static Function: To which is used in the Delegate. To call the Process()
        // function, we need to declare a logging function: Logger() that matches
        // the signature of the delegate.

        static void Logger(string s)
        {
            Console.WriteLine(s);
        }

        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();

            // Crate an instance of the delegate, pointing to the logging function.
            // This delegate will then be passed to the Process() function.

            MyClass.LogHandler myLogger = new MyClass.LogHandler(Logger);
            myClass.Process(myLogger);
        }
    }
}
Compile an test:
# csc SimpleDelegate2.cs
# SimpleDelegate2.exe
Process() begin
Process() end
In the simple example above, the Logger( ) function merely writes the string out. A different function might want to log the information to a file, but to do this, the function needs to know what file to write the information to (SimpleDelegate3.cs)
using System;
using System.IO;

namespace Akadia.SimpleDelegate
{
    // Delegate Specification
    public class MyClass
    {
        // Declare a delegate that takes a single string parameter
        // and has no return type.

        public delegate void LogHandler(string message);
        // The use of the delegate is just like calling a function directly,
        // though we need to add a check to see if the delegate is null
        // (that is, not pointing to a function) before calling the function.

        public void Process(LogHandler logHandler)
        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler ("Process() end");
            }
        }
    }

    // The FileLogger class merely encapsulates the file I/O
    public class FileLogger
    {
        FileStream fileStream;
        StreamWriter streamWriter;

        // Constructor
        public FileLogger(string filename)
        {
            fileStream = new FileStream(filename, FileMode.Create);
            streamWriter = new StreamWriter(fileStream);
        }

        // Member Function which is used in the Delegate
        public void Logger(string s)
        {
            streamWriter.WriteLine(s);
        }

        public void Close()
        {
            streamWriter.Close();
            fileStream.Close();
        }
    }

    // Main() is modified so that the delegate points to the Logger()
    // function on the fl instance of a FileLogger. When this delegate
    // is invoked from Process(), the member function is called and
    // the string is logged to the appropriate file.

    public class TestApplication
    {
        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger("process.log");

            MyClass myClass = new MyClass();

            // Crate an instance of the delegate, pointing to the Logger()
            // function on the fl instance of a FileLogger.

            MyClass.LogHandler myLogger = new MyClass.LogHandler(fl.Logger);
            myClass.Process(myLogger);
            fl.Close();
        }
    }
}
The cool part here is that we didn't have to change the Process() function; the code to all the delegate is the same regardless of whether it refers to a static or member function.
Compile an test:
# csc SimpleDelegate3.cs
# SimpleDelegate3.exe
# cat process.log
Process() begin
Process() end
Being able to point to member functions is nice, but there are more tricks you can do with delegates. In C#, delegates are multicast, which means that they can point to more than one function at a time (that is, they're based off the System.MulticastDelegate type). A multicast delegate maintains a list of functions that will all be called when the delegate is invoked. We can add back in the logging function from the first example, and call both delegates. Here's what the code looks like:
using System;
using System.IO;

namespace Akadia.SimpleDelegate
{
    // Delegate Specification
    public class MyClass
    {
        // Declare a delegate that takes a single string parameter
        // and has no return type.

        public delegate void LogHandler(string message);

        // The use of the delegate is just like calling a function directly,
        // though we need to add a check to see if the delegate is null
        // (that is, not pointing to a function) before calling the function.

        public void Process(LogHandler logHandler)

        {
            if (logHandler != null)
            {
                logHandler("Process() begin");
            }

            if (logHandler != null)
            {
                logHandler ("Process() end");
            }
        }
    }

    // The FileLogger class merely encapsulates the file I/O
    public class FileLogger
    {
        FileStream fileStream;
        StreamWriter streamWriter;

        // Constructor
        public FileLogger(string filename)
        {
            fileStream = new FileStream(filename, FileMode.Create);
            streamWriter = new StreamWriter(fileStream);
        }

        // Member Function which is used in the Delegate
        public void Logger(string s)
        {
            streamWriter.WriteLine(s);
        }


        public void Close()
        {
            streamWriter.Close();
            fileStream.Close();
        }
    }

   
 // Test Application which calls both Delegates
    public class TestApplication
    {
        
 // Static Function which is used in the Delegate
        static void Logger(string s)
        {
            Console.WriteLine(s);
        }


        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger("process.log");

            MyClass myClass = new MyClass();

            // Crate an instance of the delegates, pointing to the static
            // Logger() function defined in the TestApplication class and
            // then to member function on the fl instance of a FileLogger.

            MyClass.LogHandler myLogger = null;
            myLogger += new MyClass.LogHandler(Logger);
            myLogger += new MyClass.LogHandler(fl.Logger);


            myClass.Process(myLogger);
            fl.Close();
        }
    }
}
Compile an test:
# csc SimpleDelegate4.cs
# SimpleDelegate4.exe
Process() begin
Process() end

# cat process.log
Process() begin
Process() end

Events

The Event model in C# finds its roots in the event programming model that is popular in asynchronous programming. The basic foundation behind this programming model is the idea of "publisher and subscribers." In this model, you havepublishers who will do some logic and publish an "event." Publishers will then send out their event only to subscriberswho have subscribed to receive the specific event.
In C#, any object can publish a set of events to which other applications can subscribe. When the publishing class raises an event, all the subscribed applications are notified. The following figure shows this mechanism.
The following important conventions are used with events:
  • Event Handlers in the .NET Framework return void and take two parameters.
  • The first paramter is the source of the event; that is the publishing object.
  • The second parameter is an object derived from EventArgs.
  • Events are properties of the class publishing the event.
  • The keyword event controls how the event property is accessed by the subscribing classes.
Let's modify our logging example from above to use an event rather than a delegate:
using System;
using System.IO;

namespace Akadia.SimpleEvent
{
   
 /* ========= Publisher of the Event ============== */
    public class MyClass
    {
        // Define a delegate named LogHandler, which will encapsulate
        // any method that takes a string as the parameter and returns no value

        public delegate void LogHandler(string message);

       
 // Define an Event based on the above Delegate

       
 public event LogHandler Log;
 
 
        // Instead of having the Process() function take a delegate
        // as a parameter, we've declared a Log event. Call the Event,
        // using the OnXXXX Method, where XXXX is the name of the Event.

        public void Process()
        {
            OnLog("Process() begin");
            OnLog
("Process() end");
        }

        // By Default, create an OnXXXX Method, to call the Event
        protected void OnLog(string message)
        {
            if (Log != null)
            {
                Log(message);
            }
        }

    }

    // The FileLogger class merely encapsulates the file I/O
    public class FileLogger
    {
        FileStream fileStream;
        StreamWriter streamWriter;

        // Constructor
        public FileLogger(string filename)
        {
            fileStream = new FileStream(filename, FileMode.Create);
            streamWriter = new StreamWriter(fileStream);
        }

        // Member Function which is used in the Delegate
        public void Logger(string s)
        {
            streamWriter.WriteLine(s);
        }

        public void Close()
        {
            streamWriter.Close();
            fileStream.Close();
        }
    }
 
    /* ========= Subscriber of the Event ============== */
   
 // It's now easier and cleaner to merely add instances
    // of the delegate to the event, instead of having to
    // manage things ourselves

    public class TestApplication
    {
        static void Logger(string s)
        {
            Console.WriteLine(s);
        }

        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger("process.log");
            MyClass myClass = new MyClass();
 
            // Subscribe the Functions Logger and fl.Logger
            myClass.Log += new MyClass.LogHandler(Logger);
            myClass.Log += new MyClass.LogHandler(fl.Logger);
            // The Event will now be triggered in the Process() Method
            myClass.Process();


            fl.Close();
        }
    }
}
Compile an test:
# csc SimpleEvent.cs
# SimpleEvent.exe
Process() begin
Process() end

# cat process.log
Process() begin
Process() end
Suppose you want to create a Clock class that uses events to notify potential subscribers whenever the local time changes value by one second. Here is the complete, documented example:
using System;
using System.Threading;

namespace SecondChangeEvent
{
   /* ======================= Event Publisher =============================== */

   // Our subject -- it is this class that other classes
   // will observe. This class publishes one event:
   // SecondChange. The observers subscribe to that event.

   public class Clock
   {
      // Private Fields holding the hour, minute and second
      private int _hour;
      private int _minute;
      private int _second;

      // The delegate named SecondChangeHandler, which will encapsulate
      // any method that takes a clock object and a TimeInfoEventArgs
      // object as the parameter and returns no value. It's the
      // delegate the subscribers must implement.

      public delegate void SecondChangeHandler (
         object clock,
         TimeInfoEventArgs timeInformation
      );


      // The event we publish
      public event SecondChangeHandler SecondChange;

      // The method which fires the Event
      protected void OnSecondChange(
         object clock,
         TimeInfoEventArgs timeInformation
      )
      {
         // Check if there are any Subscribers
         if (SecondChange != null)
         {
            // Call the Event
            SecondChange(clock,timeInformation);
         }
      }


      // Set the clock running, it will raise an
      // event for each new second

      public void Run()
      {
         for(;;)
         {
            // Sleep 1 Second
            Thread.Sleep(1000);

            // Get the current time
            System.DateTime dt = System.DateTime.Now;

            // If the second has changed
            // notify the subscribers

            if (dt.Second != _second)
            {
               // Create the TimeInfoEventArgs object
               // to pass to the subscribers

               TimeInfoEventArgs timeInformation =
                  new TimeInfoEventArgs(
                  dt.Hour,dt.Minute,dt.Second);

               // If anyone has subscribed, notify them
               OnSecondChange (this,timeInformation);
            }

            // update the state
            _second = dt.Second;
            _minute = dt.Minute;
            _hour = dt.Hour;

         }
      }
   }

   // The class to hold the information about the event
   // in this case it will hold only information
   // available in the clock class, but could hold
   // additional state information

   public class TimeInfoEventArgs : EventArgs
   {
      public TimeInfoEventArgs(int hour, int minute, int second)
      {
         this.hour = hour;
         this.minute = minute;
         this.second = second;
      }
      public readonly int hour;
      public readonly int minute;
      public readonly int second;
   }

   /* ======================= Event Subscribers =============================== */
   // An observer. DisplayClock subscribes to the
   // clock's events. The job of DisplayClock is
   // to display the current time

   public class DisplayClock
   {
      // Given a clock, subscribe to
      // its SecondChangeHandler event

      public void Subscribe(Clock theClock)
      {
         theClock.SecondChange +=
            new Clock.SecondChangeHandler(TimeHasChanged);

      }

      // The method that implements the
      // delegated functionality

      public void TimeHasChanged(
         object theClock, TimeInfoEventArgs ti)
      {
         Console.WriteLine("Current Time: {0}:{1}:{2}",
            ti.hour.ToString(),
            ti.minute.ToString(),
            ti.second.ToString());
      }
   }

   // A second subscriber whose job is to write to a file
   public class LogClock
   {
      public void Subscribe(Clock theClock)
      {
         theClock.SecondChange +=
            new Clock.SecondChangeHandler(WriteLogEntry);

      }

      // This method should write to a file
      // we write to the console to see the effect

      // this object keeps no state
      public void WriteLogEntry(
         object theClock, TimeInfoEventArgs ti)
      {
         Console.WriteLine("Logging to file: {0}:{1}:{2}",
            ti.hour.ToString(),
            ti.minute.ToString(),
            ti.second.ToString());
      }
   }

   /* ======================= Test Application =============================== */
   // Test Application which implements the
   // Clock Notifier - Subscriber Sample

   public class Test
   {
      public static void Main()
      {
         // Create a new clock
         Clock theClock = new Clock();

         // Create the display and tell it to
         // subscribe to the clock just created

         DisplayClock dc = new DisplayClock();
         dc.Subscribe(theClock);

         // Create a Log object and tell it
         // to subscribe to the clock

         LogClock lc = new LogClock();
         lc.Subscribe(theClock);

         // Get the clock started
         theClock.Run();
      }
   }

}