1

ive been working on a program. i has 3 classes. 2 of the classes have timers that repeat at different intervals and once one "cycle" of the timer is done it raises an event with a string as return. the 3rd class subscribes to the events from the other two timer classes and prints them to screen. it works great!

but my issue is that it prints them separately. say currently the first timer class runs and then raises "hello" every 2 minutes and the other class "dog" every second. then every time an event is raised it prints the raised event to console. i would want it to instead print "hellodog" every second.

i was thinking: so each time a timer fires it will raise an event and update a string in the "output" class with the current value, then make another timer that goes off every second, this timer will read both the updated strings together as one output like "hellodog". is this possible if it is this is the easiest way i think. how would i achieve this idea?

if it is confusing i will clarify.

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());
        }
    }
}
Csharpz
  • 885
  • 4
  • 15
  • 25
  • 3
    possible duplicate of [How do I subscribe to raised events and printing together?](http://stackoverflow.com/questions/7375452/how-do-i-subscribe-to-raised-events-and-printing-together) – John Saunders Sep 11 '11 at 02:28
  • Also please see http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts – John Saunders Sep 11 '11 at 02:28
  • If you actually understand, then you may want to edit your question a bit. – John Saunders Sep 11 '11 at 04:16
  • done, we remove the humanism from our posts... – Csharpz Sep 11 '11 at 14:47
  • This is not a discussion forum; we're not having a conversation. It's a question and answer site, and so the "humanism" can get in the way. – John Saunders Sep 11 '11 at 18:14
  • 1
    yes i understand, i was just kidding. just as long as our whole society doesn't turn into this. (/sarcasm) – Csharpz Sep 11 '11 at 19:39

2 Answers2

1

When the events are handled in your example they have no access to information about the other events. If you want to have 2 events that update strings, but you want the handler to print data from both updated strings, you need the event handlers to have access to both of those strings. You can either store them in variables on the event handling class, or make them public properties of the classes that are raising the events. That way in either event handler you have access to the updated strings from other events.

Adam Jones
  • 711
  • 3
  • 9
1

You can use the same event handler for both timers. And construct the output by identifying the senders. (Didn't test the code for syntax errors.)

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.
    }
CharithJ
  • 46,289
  • 20
  • 116
  • 131
  • on this line if (sender == FormWithTimer) i get error is type used as variable. but maybe i can fix it. any tips? – Csharpz Sep 11 '11 at 03:19
  • 1
    Sorry it should be sender == timer1 and sender == timer2 – CharithJ Sep 11 '11 at 03:37
  • ahh thanks, but now i get an object reference is required fro the non-static method or field Output.timer1 – Csharpz Sep 11 '11 at 03:55
  • 1
    Corrected in the code. timer1 and timer2 should be static according to the logic. private static FormWithTimer timer1; private static FormWithTimer2 timer2; – CharithJ Sep 11 '11 at 04:02
  • one more(but these are warnings) Field Output.timer1 is never assigned to, and will always have its default value null. and it compiles but it just sits at a blank console, no output. – Csharpz Sep 11 '11 at 04:21
  • 1
    Corrected in the code. Don't declare timer1 and timer2 again in the Main method. – CharithJ Sep 11 '11 at 05:06
  • ok it works now! you've been a great help, now i can continue my arduino project. – Csharpz Sep 11 '11 at 14:48
  • it works sorta... so if i set one timer to 3 minutes then the other timer to 2 seconds, it waits 3 minutes then starts to print to screen every 2 seconds. But all the values are right and it prints them together, and updates correctly, just takes 3 min to start. and by the way their is syntax error in your code ...StringEventArgs>timer1_NewStringAvailable);... before timer1 should be a (. – Csharpz Sep 11 '11 at 17:14
  • 11th line down in the code box, at the end is StringEventArgs>timer1_NewStringAvailable); should be StringEventArgs>(timer1_NewStringAvailable); PS anything on how to fix the 3 minute "lag" – Csharpz Sep 12 '11 at 00:52