tags:

views:

125

answers:

4

Hi all , I'm a beginner in C# and having hard times understanding Events in C# .. The book i read (Illustrated C# 2008) gives an example about it , and there are few thing i need to ask about , so i will past the code here and point out the things i don't understand .

public class MyTimerClass
{
   public event EventHandler Elapsed;
   private void OnOneSecond(object source, EventArgs args)  
   {
     if (Elapsed != null)                
     Elapsed(source, args);
   }
}

class ClassA
{
    public void TimerHandlerA(object obj, EventArgs e) // Event handler
    {
        Console.WriteLine("Class A handler called");
    }
}

class ClassB
{
    public static void TimerHandlerB(object obj, EventArgs e) // Static
    {
        Console.WriteLine("Class B handler called");
    }
}

class Program
{
     static void Main( )
     {
         ClassA ca = new ClassA(); // Create the class object.
         MyTimerClass mc = new MyTimerClass(); // Create the timer object.
         mc.Elapsed += ca.TimerHandlerA; // Add handler A -- instance.
         mc.Elapsed += ClassB.TimerHandlerB; // Add handler B -- static.
         Thread.Sleep(2250);
     }
}

Ok, now the line after declaring the event here public event EventHandler Elapsed; which is private void OnOneSecond(object source, EventArgs args) i know that the two line after it is to check if the event contains methods or not , but what is OnOneSecound for ? or when it's called ? or what it's named .. it's not event handler i guess right ? and what's the relationship between Elapsed and OnOneSecond ?

sorry for the newbie question .. and thanks in advance :)

A: 

That allows you to manually fire the events from thein the class.

That is the standard pattern for raising internal events that's why it is private.

Rob Stevenson-Leggett
+6  A: 

the OnOneSecond method will be called internally by the MyTimerClass when it needs to invoke the event.

This is a common pattern used by most controls, including the microsoft ones.

Basically you dont need to be checking if the event is set in multiple places, you just do it in this one method then call this method internally to raise the event.

I tend not to pass the event args to the OnXXX method though, for example.

public event EventHandler<EventArgs> SomeEvent;
protected virtual void OnSomeEvent()
{
    if (this.SomeEvent !=null)
    {
        this.SomeEvent.Invoke(this,EventArgs.Empty);
    }
}

then to raise it

this.OnSomeEvent();
Richard Friend
So, what you are saying is that the OnOneSecond method is functionally just an "extra" in this example?
StingyJack
It's just not used since the MyTimerClass does nothing.
Markus
A: 

OnOneSecond is just a helper method defined to raise the event. You can use events without such methods, it is just an established pattern to wrap the if (Elapsed != null) check in a method with a name that starts with On...

Technically you could just use Elapsed(source, args) instead of OnOneSecond(source, args), but this will throw NullReferenceException if there are no listeners registered.

Grzenio
+1  A: 

This is the method, that you call to raise the event safely.

the problem is, you can basically call

Elapsed(source, args)

but if there is noone connected to the event, this will raise a Reference Null exception. as the event is null, when nobody hears on it.

a better solution is, that you directly add a subscriber to the events. then you can safely call it directly. as there will be allways a subscriber.

public event Action<EventArgs> Elapsed = val => { };

(note that with the = its directly assigned. val => { } is a Lambda expression, that defines a empty subscriber.)

Also, look into the Reactive Framework for .net if you want to do a lot of event stuff, this is the correct solution for it.

cRichter