Domanda

OK, quindi ho due classi ciascuna con timer impostati a intervalli diversi. Uno si spegne ogni 2 secondi, l'altro ogni 2 minuti. Ogni volta che il codice viene eseguito sotto il timer, voglio che sollevi un evento con la stringa di dati che il codice genera. Quindi voglio fare un'altra lezione che si iscrive all'evento Arg delle altre classi e fa qualcosa come scrivere su console ogni volta che viene licenziato un evento. E poiché una classe spara solo ogni 2 minuti questa classe può archiviare l'ultimo evento in un campo privato e riutilizzarlo ogni volta fino a quando un nuovo evento non viene licenziato per aggiornare quel valore.

Quindi, come posso sollevare un evento con la stringa di dati?, E come iscriverti a questi eventi e stampare sullo schermo o qualcosa del genere?

Questo è quello che ho finora:

    public class Output
    {
        public static void Main()
        {
            //do something with raised events here
        }
    }


    //FIRST TIMER
    public partial class FormWithTimer : EventArgs
    {
        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.Enabled = true;                       // Enable the timer
            timer.Start();                              // Start the timer
        }

      //Runs this code every 2 minutes, for now i just have it running the method        
      //(CheckMail();) of the code but i can easily modify it so it runs the code directly.
        void timer_Tick(object sender, EventArgs e)
        {
            CheckMail();             
        }

        public static string CheckMail()
        {
            string result = "0";

            try
            {
                var url = @"https://gmail.google.com/gmail/feed/atom";
                var USER = "usr";
                var PASS = "pss";

                var encoded = TextToBase64(USER + ":" + PASS);

                var myWebRequest = HttpWebRequest.Create(url);
                myWebRequest.Method = "POST";
                myWebRequest.ContentLength = 0;
                myWebRequest.Headers.Add("Authorization", "Basic " + encoded);

                var response = myWebRequest.GetResponse();
                var stream = response.GetResponseStream();

                XmlReader reader = XmlReader.Create(stream);
                System.Text.StringBuilder gml = new System.Text.StringBuilder();
                while (reader.Read())
                    if (reader.NodeType == XmlNodeType.Element)
                        if (reader.Name == "fullcount")
                        {
                            gml.Append(reader.ReadElementContentAsString()).Append(",");
                        }
                Console.WriteLine(gml.ToString());
           // I want to raise the string gml in an event
            }
            catch (Exception ee) { Console.WriteLine(ee.Message); }
            return result;
        }

        public static string TextToBase64(string sAscii)
        {
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] bytes = encoding.GetBytes(sAscii);
            return System.Convert.ToBase64String(bytes, 0, bytes.Length);
        }
    }


    //SECOND TIMER
    public partial class FormWithTimer2 : EventArgs
    {
        Timer timer = new Timer();

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

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

        //Runs this code every 2 seconds
        void timer_Tick(object sender, EventArgs e)
        {
            using (var file = MemoryMappedFile.OpenExisting("AIDA64_SensorValues"))
        {
            using (var readerz = file.CreateViewAccessor(0, 0))
            {
                var bytes = new byte[194];
                var encoding = Encoding.ASCII;
                readerz.ReadArray<byte>(0, bytes, 0, bytes.Length);

                //File.WriteAllText("C:\\myFile.txt", encoding.GetString(bytes));

                StringReader stringz = new StringReader(encoding.GetString(bytes));

                var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
                using (var reader = XmlReader.Create(stringz, readerSettings))
                {
                    System.Text.StringBuilder aida = new System.Text.StringBuilder();
                    while (reader.Read())
                    {
                        using (var fragmentReader = reader.ReadSubtree())
                        {
                            if (fragmentReader.Read())
                            {
                                reader.ReadToFollowing("value");
                                //Console.WriteLine(reader.ReadElementContentAsString() + ",");
                                aida.Append(reader.ReadElementContentAsString()).Append(",");
                            }
                        }
                    }
                    Console.WriteLine(aida.ToString());
             // I want to raise the string aida in an event
                }
            }
        }
    }
È stato utile?

Soluzione

Innanzitutto, farei una classe di base che ha gestito la logica relativa all'evento. Ecco un esempio:

/// <summary>
/// Inherit from this class and you will get an event that people can subsribe
/// to plus an easy way to raise that event.
/// </summary>
public abstract class BaseClassThatCanRaiseEvent
{
    /// <summary>
    /// This is a custom EventArgs class that exposes a string value
    /// </summary>
    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;

    /// <summary>
    /// Helper method that raises the event with the given string
    /// </summary>
    protected void RaiseEvent(string value)
    {
        var e = NewStringAvailable;
        if(e != null)
            e(this, new StringEventArgs(value));
    }
}

Quella classe dichiara una classe EventArgs personalizzata per esporre il valore della stringa e un metodo di helper per l'evento. Una volta aggiornati i tuoi timer per ereditare da quella classe, sarai in grado di fare qualcosa del tipo:

RaiseEvent(aida.ToString());

Puoi iscriverti a questi eventi come qualsiasi altro evento in .NET:

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

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

    //Same for timer2
}

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

    //To something with 'theString' that came from timer 1
    Console.WriteLine("Just got: " + theString);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top