views:

517

answers:

3

I want to create a class that initializes a timer which will be used as a central core for other class members to register themselves for the timer elapsed event. My problem is that I don't really know how to expose the timer elapsed event to other classes. One solution, that I think might work is that I simply expose the timer as a public property which will return the timer object and I can call the timer elapsed event from this object, for example:

MyAppTimer appTimer = new MyAppTimer();
Timer timer = appTimer.GetAppTimer;
timer.Elapsed += SomeMethod;

But with this solution I will be exposing the entire timer which I don't want. How can I pass in a method in the MyAppTimer class which will register the method with the timer's elapsed event internally? Is it something to do with delegates? Maybe something like:

public void RegisterHandler(someStuffGoesHere) //What do I pass in here?
{
  timer.Elapsed += someStuffGoesHere;
}
+2  A: 

You can create an event with explicit accessors :

public event EventHandler TimerElapsed
{
    add { timer.Elapsed += value; }
    remove { timer.Elapsed -= value; }
}

The clients of your class can subscribe directly to the TimerElapsed event :

appTimer.TimerElapsed += SomeHandlerMethod;

If you want to use a RegisterHandler method as shown in your code, the type of the parameter should be EventHandler

EDIT: note that with this approach, the value of sender parameter will be the Timer object, not the MyAppTimer object. If that's a problem, you can do that instead :

public MyAppTimer()
{
    ...
    timer.Elapsed += timer_Elapsed;
}

private void timer_Elapsed(object sender, EventArgs e)
{
    EventHandler handler = this.TimerElapsed;
    if (handler != null)
        handler(this, e);
}
Thomas Levesque
This is what I have been looking for...thanx :)
Draco
Looking at that code again, I see that it has a drawback : the value of sender parameter will be the Timer object, not the MyAppTimer object... it could be a problem if you need to know the sender. I'll update my answer for a workaround
Thomas Levesque
A: 

You want to expose an Event on your class, something like:

class A
{
    public event EventHandler<EventArgs> Elapsed;

    private void OnElapsed()
    {
         if(Elapsed!=null)
                 Elapsed(new EventArgs());
    }
}

in the OnElapsed private method you have an example how to raise the event. You then use the class A in the same way you would use Timer.

Grzenio
+2  A: 

As others have mentioned, exposing an Event is probably the way you want to go, but to answer your question about the type required in your RegisterHandler method, it would look something like:

using System.Timers;

...snip...

public void RegisterHandler(ElapsedEventHandler callback)
{
  timer.Elapsed += callback;
}
Andy Whitfield