Monday, September 29, 2008

Delegates in C#.net



In C#, delegates represent methods that are callable without knowledge of the target object. Delegates enable scenarios that some other languages have addressed with function pointers. However, unlike function pointers, delegates are object-oriented and type-safe.


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.


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 which function 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, and invocation.



Delegate Declaration:


public class DeligateClass

{

public DeligateClass()

{

}


// Declare a delegate

public delegate void MessageHandler(string message);

// The use of the delegate.


public void Process(MessageHandler handler)

{

if (handler != null)

handler("Begin Message");

if (handler != null)

handler("End Message");

}

}



Function Class:



This class contains the functions will be called by delegates



public class FunctionClass

{

public FunctionClass()

{

}


//This method will show alert message to user

public static void AlertMessage(string s)

{

System.Windows.Forms.MessageBox.Show(s);

}


//This method will write output to console

public static void ConsoleMessage(string s)

{

Console.WriteLine(s);

}

}


Instantiation and Invocation:


Client Application to use the defined Delegate



Simple Delegate



Create a windows form and add one button to it and paste the following code on its click event.



private void button1_Click(object sender, System.EventArgs e)

{

//Instantiating a delegate

DeligateClass dc = new DeligateClass();

DeligateClass.MessageHandler ll = null;

ll += new DeligateClass.MessageHandler(FunctionClass.AlertMessage);

//Calling a delegate

dc.Process(ll);

}


When you will click on button1, it will show 'Begin Message' and 'End Message' message box.


Multicast Delegate


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.


Add one more button to form with following code.



private void button2_Click(object sender, System.EventArgs e)

{

DeligateClass dc = new DeligateClass();

DeligateClass.MessageHandler ll = null;

ll += new DeligateClass.MessageHandler(FunctionClass.AlertMessage);

ll += new

DeligateClass.MessageHandler(FunctionClass.ConsoleMessage);

dc.Process(ll);

}




When you will click on button2, in addition to 'Begin Message' and 'End Message' message box, it will also write to console of visual studio (VS).



Delegates and interfaces are similar in that they enable the separation of specification and implementation. Multiple independent authors can produce implementations that are compatible with an interface specification. Similarly, a delegate specifies the signature of a method, and authors can write methods that are compatible with the delegate specification.

There are direction defined by Microsoft when to use delegate and when to use interface.



Delegates are ideally suited for use as events - notifications from one component to "listeners" about changes in that component.



Regards,

Paresh Bhole

Events & Delegates in C#.net



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 have publishers who will do some logic and publish an "event." Publishers will then send out their event only to subscribers who 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.



















Conventions:


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.


Simple Event:


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 a test:


# csc SimpleEvent.cs
# SimpleEvent.exe
Process() begin
Process() end
# cat process.log
Process() begin
Process() end


The Second Change Event Example:


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();
}
}
}


What you study:


The Clock class from the last sample could simply print the time rather tahn raising an event, so why bother with the introduction of using delegates? The advantage of the publisg / subscribe idiom is that any number of classes can be notified when an event is raised. The subscribing classes do not need to know how the Clock works, and the Clock does not need to know what they are going to do in response to the event. Similarly a button can publish an Onclick event, and any number of unrelated objects can subscribe to that event, receiving notification when the button is clicked.


The publisher and the subscribers are decoupled by the delegate. This is highly desirable as it makes for more flexible and robust code. The clock can chnage how it detects time without breaking any of the subscribing classes. The subscribing classes can change how they respond to time changes without breaking the Clock. The two classes spin indepentdently of one another, which makes for code that is easier to maintain.



Regards,

Paresh Bhole


Wednesday, September 24, 2008

Web Service performance overhead

We are going to discuss the topic with example.

Because a web service requires the exchange of network messages and because the server that executes the web service may be busy performing other tasks (thus delaying its execution of the service you desire), a web service will execute much slower than a standard function.


To get the feel (to verify) of this Overhead let’s create a short & simple test:


Step 1: Create a Web Service and write down a simple Hello World method as shown below:

[WebMethod]

public string HelloWorld()

{

return "Hello World";

}


Step 2: Now, create a simple Web Application and create the same private method in the web page:

private string GetHelloWorld()

{

return "Hello World";

}


Step 3: Now create two buttons followed by label on the page as shown:










Step 4: Finally you are ready to call these two methods on click:

protected void btnLocalCall_Click(object sender, EventArgs e)

{

HelloWorld.Service1 hello = new HelloWorld.Service1();

long start_tick, end_tick;

start_tick = DateTime.Now.Ticks;

for (int count = 0; count <>

{

lblLocalCall.Text = GetHelloWorld();

}

end_tick = DateTime.Now.Ticks;

lblLocalCall.Text = "Tick: " + (end_tick - start_tick).ToString();

}


protected void btnServiceCall_Click(object sender, EventArgs e)

{

HelloWorld.Service1 hello = new HelloWorld.Service1();

long start_tick, end_tick;

start_tick = DateTime.Now.Ticks;

for (int count = 0; count <>

{

lblServiceCall.Text = hello.HelloWorld();

}

end_tick = DateTime.Now.Ticks;

lblServiceCall.Text = "Tick: " + (end_tick - start_tick).ToString();

}



Result: Just check the results below:









When the user clicks the “Call Local..” button, the program code will call the local functions within a for loop to get values 100 times. Because the functions reside in RAM, the program can complete its processing very quickly. When the user clicks the “Call Service…” web button, the program will use the “HelloWorld” web service methods within a for loop to get values 100 times. The network overhead of the web service calls causes the operations to execute much slower. The program displays the number of clock ticks each swap operation required within the text boxes.


Because network overhead makes a web service execute much slower than a standard function, many operations are not well suited for implementation as a web service. Using a web service to add two numbers, for example, or to calculate a random number, would introduce unnecessary overhead to a program. Such operations are better suited for implementation using standard functions.


Web services, in contrast, are ideal for operations that use data residing at a remote source (most often within a database on a specific server). For example, web services are well suited for the following operations:


  • Responding to queries for stock quotes
  • Returning information regarding the availability of specific inventory items
  • Providing real-time information, such as weather and road conditions
  • Offering airline flight arrival and departure information
  • Implementing e-commerce operations, such as ticket sales for movies and special events
  • Authenticating users or credit-card information

You may be saying to yourself that users already perform such operations on many sites across the Web. Web services provide programmers with a way to integrate these operations into their programs. By using web services to implement common user operations (such as downloading stock quotes, ordering a book, and checking the weather) within your company’s website, you can keep users from leaving your website to perform these operations elsewhere. By taking advantage of web services, you can integrate powerful processing developed by other programmers into your applications and web pages.


One can cross check calling second web service within the first to check the overhead, it goes twice.


Hope this helps you understanding Web Service Performance Overhead.


Ref:

.NET Web Services Solutions

by Kris Jamsa



Regards,

Paresh Bhole


Hello

Thanks for checking out my post...

... Paresh Bhole