Domanda

Ho lavorato su un programma che ha 3 classi di cui 2 delle classi hanno timer che si ripetono a intervalli diversi e una volta che un "ciclo" del timer viene fatto, solleva un evento con una stringa come ritorno. La terza classe si iscrive agli eventi delle altre due classi di timer e li stampa sullo schermo. Funziona alla grande!

Ma il mio problema è che li sta stampando separatamente. Diciamo che la prima lezione di timer corre e poi solleva "ciao" ogni 2 minuti e l'altra classe "cane" ogni secondo e ogni volta che viene sollevato un evento stampica l'evento rialzato su console. Vorrei che stampino invece "Hellodog" ogni secondo e memorizzerei il valore del primo timer (ciao) in un campo privato o qualcosa del genere, quindi stampela ancora per lo screening anche se il timer (il timer più lento di 2 minuti) non è stato licenziato. E quando il timer di 2 minuti spara aggiorna il valore a qualunque sia il nuovo e quel nuovo valore viene stampato sullo schermo fino a quando non spara di nuovo.

Se è confuso, chiarirò volentieri. È un po 'difficile da spiegare.

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());
        }
    }
}
È stato utile?

Soluzione

Puoi utilizzare lo stesso gestore di eventi per entrambi i timer. E costruire l'output identificando i mittenti. (Non ha testato il codice per errori di sintassi.)

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.
    }

Altri suggerimenti

Correggimi se fraintendo la domanda, ma sembra che tu voglia coordinare la tua risposta ai due eventi del timer (stampa "Hellodog").

Mi sembra che il modo più semplice per farlo sia solo usare un singolo timer e far contare il gestore degli eventi del timer il numero di volte in cui il gestore è stato invocato per decidere se intraprendere l'azione un tempo per secondo o anche Prendi l'azione un tempo per due minuti.

Poiché il timer lento è un multiplo esatto del tuo timer veloce, imposteresti solo un timer che innesca ogni secondo e fai anche l'azione di 2 minuti ogni 120 invocazioni del timer da 1 secondo (120 secondi = 2 minuti).

Penso di capire cosa vuoi e cioè sincronizzare l'output di entrambi i timer. Temo che non c'è modo di farlo se non quello di sfogliare. Imposta un sacco di variabili booleane che tracciano se ogni evento ha sparato e se il messaggio sincronizzato è stato inviato all'output.

Questo dovrebbe fare quello che vuoi.

    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();
    }

Fammi sapere se è giusto. Saluti.

Il secondo timer (più veloce) dovrebbe essere l'unico a stampare. Il primo timer (più lento) dovrebbe aggiornare solo una stringa che il secondo timer utilizzerà.

Nella classe "output" (puoi metterlo prima di Main):

string string1;

poi:

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top