如何用计时器引发事件

本文关键字:事件 计时器 何用 | 更新日期: 2023-09-27 18:08:03

好的,所以我有两个类,每个类的计时器设置在不同的间隔。一个每两秒响一次,另一个每两分钟响一次。每次代码在计时器下运行时,我希望它用代码生成的数据字符串引发一个事件。然后,我想创建另一个类,它从其他类订阅事件参数,并在事件触发时向控制台写入类似的内容。由于一个类每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
                }
            }
        }
    }

如何用计时器引发事件

首先,我将创建一个处理与事件相关的逻辑的基类。下面是一个例子:

/// <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类来公开字符串值和引发事件的helper方法。一旦你更新了你的定时器来继承这个类,你就可以做如下的事情:

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