tags:

views:

205

answers:

4

I need help trying to understand the Observer Pattern and Delegates. I found this code on another website and I am trying to understand what it is actually doing. Can someone help me out.

When I execute the code, I get both of the messages "Server is up and running" and "Server is down, We are working on it it will be back soon". I think I am getting both of the message because in the Main, there is a server.ServerStatus = true; and a server.ServerStatus = false. However, if I comment out the server.ServerStatus = true; and run then I I get the message "Server is up and running" but I expected to only see "Server is down, We are working on it it will be back soon.". Can someone explain? Susan

class Program
{
    static void Main(string[] args)
    {
        Server server = new Server();
        server.ServerStatusChanged += new EventHandler(ProcessServerStatus);
        server.ServerStatus = true; 
        server.ServerStatus = false;
        Console.Read();
    }


    public class Server
    {
        public event EventHandler ServerStatusChanged;
        private bool _ServerStatus;

        public bool ServerStatus
        {
            get { return this._ServerStatus; }
            set {
                if (this._ServerStatus == value) return; // Dont need to do anything;
                if (this.ServerStatusChanged != null) // make sure the invocation list is not empty  
                    ServerStatusChanged(value, new EventArgs());  // Firing Event
                this._ServerStatus = value; 
            } 
        }
    }



    public static void ProcessServerStatus(object sender, EventArgs e)
    {
        bool status = (bool)sender; 
        if (status)
            Console.WriteLine("Server is up and running");
        else
            Console.WriteLine("Server is down, We are working on it it will be back soon");

    }



}
A: 

This is an event registration ...

server.ServerStatusChanged += new EventHandler(ProcessServerStatus);

It says "whenever there is a ServerStatusChanged, call the ProcesServerStatus method." So, when you set the ServerStatus to true, you get a call to ProcessServerStatus passing true and it prints "Server is up..."; when you change it to false, another event is fired, but this time ServerStatus is false, so you get "Server is down ..." So, you are watching the server status and doing something (ProcessServerStatus) when it changes.

JP Alioto
A: 

Essentially what is occuring is that the assignments you have in Main that are setting ServerStatus to true/false will call the "set" function of the ServerStatus property.

Within that function, an event is created and fired to the ServerStatusChanged handler, which will be received by anyone who registered for events. Also note that the event is fired only if the status changes.

In this case, Main registered for the event in the

Server.ServerStatusChanged += new EventHandler(ProcessServerStatus);

line.

Since you set ServerStatus to true, then false in Main, two events are fired, causing your console to display both "Server is up and running", and "Server is down, We are working on it...."

Snazzer
+2  A: 

Here is code that does what you want.

Notice the _initialized variable. This is needed because otherwise nothing happens the the first time through. You would have to set the status to True before it starts working correctly.

Also, I what you describe didn't happen for me. I didn't get the message saying it was up and running. I didn't get anything at all.

    class Program
{
    static void Main(string[] args)
    {
        Server server = new Server(); 
        server.ServerStatusChanged += new EventHandler(ProcessServerStatus); 
        //server.ServerStatus = true; 
        server.ServerStatus = false; 
        Console.Read();
    }

    public class Server
    {
        public event EventHandler ServerStatusChanged; 
        private bool _ServerStatus = false;
        private bool _initialized = false;
        public bool ServerStatus
        {
            get { return this._ServerStatus; }
            set
            {
                if (this._initialized == true && this._ServerStatus == value)
                    return; // Dont need to do anything;                
                else
                    this._initialized = true;
                if (this.ServerStatusChanged != null) // make sure the invocation list is not empty                      
                    ServerStatusChanged(value, new EventArgs());  // Firing Event                
                this._ServerStatus = value;
            }
        }
    }
    public static void ProcessServerStatus(object sender, EventArgs e)
    {
        bool status = (bool)sender;
        if (status)
            Console.WriteLine("Server is up and running");
        else Console.WriteLine("Server is down, We are working on it it will be back soon");
    }
}
awhite
Without initializing the ServerStatus value, I thinkyou were getting unpredictable results, i.e. "Server is running..." and further because the setter is only conditionally calling the ProcessServerStatus method, you were not getting the "SErver is down ..." message
simon
A: 

If you haven't come across the Observer pattern before, it might be instinctive to think that all method calls are done quite statically - the methods we call in our code are what's called. However, the observer pattern lets you do things more dynamically. You can have something say at runtime "hey, when such and such happens, let me know! You can let me know by calling such and such a method" The one being observed keeps a record of everyone that has said to it "when such and such happens, let me know" - and then, when it happens, it does just that - lets all of them know. This is done by keeping a list of the methods which must be called, and then calling them all when the event is 'triggered'.

The line:

server.ServerStatusChanged += new EventHandler(ProcessServerStatus);

is telling the server object "hey, when the server status is changed, let me know. You can let me know by calling the ProcessServerStatus method". And so, when the line:

server.ServerStatus = true;

is run, it triggers the ServerStatusChanged event, which then calls everything that has said "let me know". So it will call the ProcessServerStatus method, since that's the only method in its list.

Every method that is in that list must have a certain method signature; in this case, void ProcessServerStatus(object sender, EventArgs e). The sender parameter in this case is the server status - you can see this in the line:

ServerStatusChanged(value, new EventArgs());

And so when ProcessServerStatus is called, it casts it so a boolean value, and prints the appropriate string.

When I run this code, it works as expected - if I comment out the serverStatus = true; line, it prints nothing (since _serverStatus defaults to false, and the event is not triggered if the status hasn't changed). Instead, if I comment out the serverStatus = false; line, it says "the server is up and running"

Smashery