Как подписаться на поднятые события и печатать вместе? - PullRequest
3 голосов
/ 11 сентября 2011

Я работал над программой, в которой есть 3 класса, из которых у 2 из классов есть таймеры, которые повторяются с разными интервалами, и после того, как один «цикл» таймера завершен, он вызывает событие со строкой в ​​качестве возврата.Третий класс подписывается на события двух других классов таймера и выводит их на экран.он отлично работает!

Но моя проблема в том, что он печатает их отдельно.Допустим, первый класс таймера запускается, а затем выдает «привет» каждые 2 минуты, а другой класс «собака» - каждую секунду, и каждый раз, когда возникает событие, он выводит вызванное событие на консоль.Я бы хотел, чтобы вместо этого он печатал «hellodog» каждую секунду и сохранял значение первого таймера (hello) в приватном поле или что-то в этом роде, чтобы он по-прежнему печатался на экране, даже если таймер (более медленный 2-минутный таймер) не былуволена.и когда срабатывает 2-минутный таймер, он обновляет значение до того, что является новым, и это новое значение выводится на экран до тех пор, пока оно не сработает снова.

Если это сбивает с толку, я с удовольствием уточню.это трудно объяснить.

namespace Final
{
    public class Output
    {
        public static void Main()
        {
            var timer1 = new FormWithTimer();
            var timer2 = new FormWithTimer2();

            timer1.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);

            timer2.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer2_NewStringAvailable);
            Console.ReadLine();
        }

        static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
        {
            var theString = e.Value;

            //To something with 'theString' that came from timer 1
            Console.WriteLine(theString);
        }

        static void timer2_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
        {
            var theString2 = e.Value;

            //To something with 'theString2' that came from timer 2
            Console.WriteLine(theString2);
        }
    }

    public abstract class BaseClassThatCanRaiseEvent
    {
        public class StringEventArgs : EventArgs
        {
            public StringEventArgs(string value)
            {
                Value = value;
            }

            public string Value { get; private set; }
        }

        //The event itself that people can subscribe to
        public event EventHandler<StringEventArgs> NewStringAvailable;

        protected void RaiseEvent(string value)
        {
            var e = NewStringAvailable;
            if (e != null)
                e(this, new StringEventArgs(value));
        }
    }

    public partial class FormWithTimer : BaseClassThatCanRaiseEvent
    {
        Timer timer = new Timer();

        public FormWithTimer()
        {
            timer = new System.Timers.Timer(200000);

            timer.Elapsed += new ElapsedEventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
            timer.Interval = (200000);             // Timer will tick evert 10 seconds
            timer.Enabled = true;                       // Enable the timer
            timer.Start();                              // Start the timer
        }

        void timer_Tick(object sender, EventArgs e)
        {
            ... 
            RaiseEvent(gml.ToString());                    
        }
    }


    public partial class FormWithTimer2 : BaseClassThatCanRaiseEvent
    {
        Timer timer = new Timer();

        public FormWithTimer2()
        {
            timer = new System.Timers.Timer(1000);

            timer.Elapsed += new ElapsedEventHandler(timer_Tick2); // Everytime timer ticks, timer_Tick will be called
            timer.Interval = (1000);             // Timer will tick evert 10 seconds
            timer.Enabled = true;                       // Enable the timer
            timer.Start();                              // Start the timer
        }

        void timer_Tick2(object sender, EventArgs e)
        {
            ...
            RaiseEvent(aida.ToString());
        }
    }
}

Ответы [ 5 ]

1 голос
/ 12 сентября 2011

Второй (более быстрый) таймер должен быть единственным для печати.Первый (более медленный) таймер должен обновлять только строку, которую будет использовать второй таймер.

В классе «Выход» (вы можете поместить его перед Main):

string string1;

, а затем:

static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
    string1 = e.Value;
}

static void timer2_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
    var theString2 = e.Value;

    //To something with 'theString2' that came from timer 2
    Console.WriteLine(string1 + theString2);
}
1 голос
/ 11 сентября 2011

Это должно делать то, что вы хотите.

    public static void Main()
    {
        var timer1 = new FormWithTimer();
        var timer2 = new FormWithTimer2();

        var value1 = "";
        var value2 = "";

        Action writeValues = () => Console.WriteLine(value1 + value2);

        timer1.NewStringAvailable += (s, e) =>
        {
            value1 = e.Value;
            writeValues();
        };

        timer2.NewStringAvailable += (s, e) =>
        {
            value2 = e.Value;
            writeValues();
        };

        Console.ReadLine();
    }

Дайте мне знать, если это правильно. Приветствия.

1 голос
/ 11 сентября 2011

Я думаю, я понимаю, что вы хотите, и это синхронизировать выход обоих таймеров. Боюсь, что нет другого способа сделать это, кроме как пройти через это. Установите набор булевых переменных, которые отслеживают, было ли каждое событие запущено и было ли синхронизированное сообщение отправлено на выход.

1 голос
/ 11 сентября 2011

Вы можете использовать один и тот же обработчик событий для обоих таймеров.И создайте вывод, идентифицируя отправителей.(Не проверял код на наличие синтаксических ошибок.)

private static string timer1Value = string.Empty;
private static string timer2Value = string.Empty;
private static FormWithTimer timer1;
private static FormWithTimer2 timer2;

public static void Main()
{
    timer1 = new FormWithTimer();
    timer2 = new FormWithTimer2();

    timer1.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);

    timer2.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);
    Console.ReadLine();
}


static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
    if (sender == timer1)
    {
        timer1Value = e.Value.ToString();
    }
    else if (sender == timer2)
    {
        timer2Value = e.Value.ToString();
    }

    if (timer1Value != String.Empty && timer2Value != String.Empty)
    {
        Console.WriteLine(timer1Value + timer2Value); 
        // Do the string concatenation as you want.
    }
1 голос
/ 11 сентября 2011

Поправьте меня, если я неправильно понял вопрос, но звучит так, будто вы хотите скоординировать свой ответ на два события таймера (выведите «hellodog»).

Мне кажется, что самый простой способ сделать этосостоит в том, чтобы просто использовать один таймер, и обработчик события таймера подсчитывает, сколько раз был вызван обработчик, чтобы решить, следует ли выполнять действие один раз в секунду, или также выполнять действие один раз в две минуты.

Поскольку медленный таймер является точным кратным вашего быстрого таймера, вы должны установить только один таймер, который срабатывает каждую секунду, а также выполнять 2-минутное действие каждые 120 вызовов 1-секундного таймера (120 секунд =2 минуты).

...