c# манипулаторът на събития се добавя два пъти

Това е измислен пример, но се чудех какво се случва, ако функцията InitialiseTimer бъде извикана два пъти. Функцията за изминал таймер задейства ли се два пъти. Ще се промени ли това, ако функциите станат статични?

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

    public void TheTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //Do stuff in here
    }

Щях да използвам по-долу, за да предотвратя това

Добавен ли е вече манипулатор на събития?

Благодаря, Ричард


person probably at the beach    schedule 03.03.2011    source източник


Отговори (5)


Мисля, че следното демонстрира сценария и наистина се задейства два пъти, също предлага проста промяна (коментиран код) на метода Init, който трябва да коригира поведението. (Между другото не е безопасно за нишки, ще са необходими допълнителни брави)

[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);
        }
    }
}
person Perry    schedule 03.03.2011

Ако регистрирате манипулатора на събитие два пъти, той ще бъде извикан два пъти при всяко възникване на събитието.

Това няма да се промени, ако направите TheTimer_Elapsed статичен, защото все още ще имате две препратки към този статичен метод.

В повечето случаи няма нужда да пишете сложни неща като това, което Блеър Конрад публикува във въпроса, към който сте дали връзка. Само не забравяйте да използвате -= всеки път, когато имате += и ще сте в безопасност.

person Ilya Kogan    schedule 03.03.2011

ако извикате метода InitialiseTimer два пъти, вие ще създадете два таймера, всеки от тях ще има само един прикачен манипулатор на събития, но те може да изтекат и двата. Всъщност не става дума за това дали методът е статичен или не, а по-скоро за самия метод, можете да проверите дали TheTimer е null и да направите останалото само ако е null, така че да го присвоите само веднъж.

person Davide Piras    schedule 03.03.2011

Ако събитието е регистрирано два пъти, ще имате две изпълнения.

Можете да проверите дали събитието е нула и проблемът ще бъде решен.

person buda    schedule 03.03.2011
comment
Как проверката за нула решава това? Ами ако други манипулатори са регистрирани за това събитие? - person Ilya Kogan; 03.03.2011
comment
Това би било нулева проверка на новосъздадения екземпляр Timer, а не този, който е създаден в предишното извикване, така че това всъщност не решава нищо. Въпреки това, нулевата проверка на полето TheTimer ще реши проблема. - person Fredrik Mörk; 03.03.2011
comment
Разбира се, мислех, че ще трябва да проверите дали събитието е нула на същия таймер, а не на новосъздадения. - person buda; 03.03.2011

Статичен или не, вие пресъздавате таймера. Така че можете да извиквате InitialiseTimer много, много пъти, без да добавяте повече от един манипулатор. В крайна сметка обаче ще имате много таймери...

person Emond Erno    schedule 03.03.2011