开发者

c# event handler being added twice

This is a fictional example but I was wandering what happens if the InitialiseTimer function gets called twice. Does the timer elapsed function get triggered twice. Will this change if the functions are made static?

    private static void InitialiseTimer()
    {
            TheTimer = new System.Timers.Timer();
            TheTimer.Interval = 400;
            TheTimer.Elapsed += new ElapsedEventHandler(TheTimer_Elapsed);
            TheTimer.AutoReset = false;
    }   

    public开发者_Go百科 void TheTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //Do stuff in here
    }

I was going to use below to prevent this

Has an event handler already been added?

Thanks, Richard


If you register the event handler twice, it will be invoked twice every time the event is raised.

This won't change if you make TheTimer_Elapsed static, because you'll still hold two references to this static method.

In most cases there's no need to write compicated things like what Blair Conrad posted in the question you linked to. Just don't forget to use -= every time you have += and you'll be safe.


I think the following demonstrates the scenario and does indeed fire twice, also propose a simple change (commented code) to the Init method that should fix the behavior. (Not thread safe btw, additional locks would be required)

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var counter = 0;
        var ts = new ThreadStart(() =>
            {

                Foo.Fired += (o, e) =>
                    {
                        counter++;
                    };
                Foo.InitialiseTimer();
                Foo.InitialiseTimer();
            });
        var t = new Thread(ts);
        t.Start();

        Thread.Sleep(30);
        Assert.AreEqual(1, counter);
    }
}

public class Foo
{
    private static System.Timers.Timer TheTimer = null;

    public static event EventHandler Fired;

    public static void InitialiseTimer()
    {
        //if (TheTimer != null)
        //{
        //    TheTimer.Stop();
        //    TheTimer = null;
        //}
        TheTimer = new System.Timers.Timer();
        TheTimer.Interval = 10;
        TheTimer.Elapsed += new ElapsedEventHandler(TheTimer_Elapsed);
        TheTimer.AutoReset = false;
        TheTimer.Start();
    }

    public static void TheTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //Do stuff in here
        if (Fired != null)
        {
            Fired(null, null);
        }
    }
}


if you call the method InitialiseTimer twice you will create two Timers each of them will have only one event handler attached but they might elapse both. It's not really about having the method static or not, it's more about the method itself, you could check if TheTimer is null and do the rest only if it's null so you assign it only once.


If event is registered twice you will have two executions.

You can check if event is null, and the problem will be solved.


Static or not, you are recreating the Timer. So you can invoke the InitialiseTimer many, many times without adding more than a single handler. You will end up with many timers though...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜