как поднять событие с таймером? - PullRequest
2 голосов
/ 10 сентября 2011

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

Итак, как мне вызвать событие со строкой данных? И как подписаться на эти события и распечатать на экране или что-то в этом роде?

вот что у меня есть:

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

1 Ответ

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

Во-первых, я бы создал базовый класс, который обрабатывает логику, связанную с событием. Вот пример:

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

Этот класс объявляет пользовательский класс EventArgs для представления строкового значения и вспомогательный метод для вызова события. Как только вы обновите свои таймеры для наследования от этого класса, вы сможете сделать что-то вроде:

RaiseEvent(aida.ToString());

Вы можете подписаться на эти события, как и любое другое событие в .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);
}
...