简体   繁体   中英

Need help understanding Events in C#

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 :)

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

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM