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