I have to create several timers dynamically but I need the name of them when they fire.
Here is my code:
timersDict = new Dictionary<string, System.Timers.Timer>();
int i = 0;
foreach (var msg in _messages.CurrentMessages)
{
var timer = new System.Timers.Timer();
timer.Interval = int.Parse(msg.Seconds);
timer.Elapsed += Main_Tick;
timer.Site.Name = i.ToString();
i++;
}
I thought I could set it from timer.Site.Name but I get a null exception on Site.
How do I set the name of the timer I am creating?
EDIT
I am creating this since I need to know what timer is firing when it gets to the elapsed event. I have to know what message to display once it fires.
Can I pass the message with the timer and have it display the message based on what timer it is?
Here is the rest of my code:
void Main_Tick(object sender, EventArgs e)
{
var index = int.Parse(((System.Timers.Timer)sender).Site.Name);
SubmitInput(_messages.CurrentMessages[index].MessageString);
}
I was going to use it's name to tell me which timer it was so I know what message to display since all of the timers are created dynamically.
I'd recommend wrapping the System.Timers.Timer class and add your own name field.
Here is an example:
using System;
using System.Collections.Generic;
using System.Threading;
namespace StackOverFlowConsole3
{
public class NamedTimer : System.Timers.Timer
{
public readonly string name;
public NamedTimer(string name)
{
this.name = name;
}
}
class Program
{
static void Main()
{
for (int i = 1; i <= 10; i++)
{
var timer = new NamedTimer(i.ToString());
timer.Interval = i * 1000;
timer.Elapsed += Main_Tick;
timer.AutoReset = false;
timer.Start();
}
Thread.Sleep(11000);
}
static void Main_Tick(object sender, EventArgs args)
{
NamedTimer timer = sender as NamedTimer;
Console.WriteLine(timer.name);
}
}
}
Related
I'm new to c# and currently working on a program. it has a simple UI, there are two buttons (one is called on and other one is off) and also a textbox to show some result. basically what I want to do is that if the user click "on" button, on a different class than the windows form random numbers will be generated every one second using a method. and by Implementing INotifyPropertyChanged I want to let the Textbox know that the value was updated so textbox keeps getting updated with our new random number. and once user click "off" button I want to stop generating random number.
My windows Form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SWE_Assignment
{
public partial class Monitor : Form
{
Patient newPatient = Patient.Instance;
public static bool pulseRateOn = false;
public Monitor()
{
InitializeComponent();
newPatient.PropertyChanged += _PulseRate_PropertyChanged;
}
private void Save_Click(object sender, EventArgs e)
{
// newPatient.PL(newPatient.startRnd = true;);
}
void _PulseRate_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "PulseRate")
{
HeartBeat.Text = newPatient.PulseRate.ToString();
}
}
private void Stop_Click(object sender, EventArgs e)
{
newPatient.startRnd = false;
}
}
}
My Patient Class
namespace SWE_Assignment
{
class Patient : INotifyPropertyChanged
{
private int _pulseRate;
public bool startRnd = false;
Random rnd = new Random();
public int PulseRate
{
get { return _pulseRate; }
set
{
_pulseRate = value;
OnPropertyChanged("PL");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string properyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(properyName));
}
private static Patient _instance = null;
private static readonly object _padlock = new object();
public static Patient Instance
{
get
{
lock (_padlock)
{
if (_instance == null)
{
_instance = new Patient();
}
return _instance;
}
}
}
public void PL(bool srt)
{
Timer timer = new Timer();
timer.AutoReset = true;
timer.Interval = 1000;
if (startRnd == true)
{
timer.Elapsed += PLS;
timer.Enabled = true;
timer.Start();
} else
{
timer.Enabled = false;
timer.Stop();
}
}
private void PLS(object sender, ElapsedEventArgs e)
{
PulseRate = rnd.Next(100, 150);
Console.WriteLine(PulseRate);
}
}
}
Also my I am using singleton pattern for my patient because I want to only have on instance of patient so that I can have access to the same random number on another class (called Alarm) to check if its bigger or smaller than a certain numbers. I do realise that is wrong with my "Stop" button as it only calls the method again and it doesn't stop method from running. I appreciate if anyone can help.
there are a few things which need to be changed.
OnPropertyChanged("PL"); - the name of property is PulseRate. "PulseRate" is what you check in event handler. make it OnPropertyChanged("PulseRate");
Timer timer = new Timer(); - you should create only one instance of Timer per Patient. better do it in constructor. otherwise you will have multiple running copies of Timer
managing Timer can be done via Enabled property:
Calling the Start() method is the same as setting Enabled to true. Likewise, calling the Stop() method is the same as setting Enabled to false.
private void Stop_Click(object sender, EventArgs e)
{
// newPatient.startRnd = false;
newPatient.PL(false);
}
class Patient : INotifyPropertyChanged
{
Timer timer;
private Patient()
{
timer = new Timer();
timer.AutoReset = true;
timer.Interval = 1000;
timer.Elapsed += PLS;
}
Random rnd = new Random();
private int _pulseRate;
public int PulseRate
{
get { return _pulseRate; }
set
{
_pulseRate = value;
OnPropertyChanged("PulseRate");
}
}
public void PL(bool srt)
{
timer.Enabled = srt;
}
private void PLS(object sender, ElapsedEventArgs e)
{
PulseRate = rnd.Next(100, 150);
Console.WriteLine(PulseRate);
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string properyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(properyName));
}
private static Patient _instance = null;
private static readonly object _padlock = new object();
public static Patient Instance
{
get
{
lock (_padlock)
{
if (_instance == null)
{
_instance = new Patient();
}
return _instance;
}
}
}
}
I have several projects and one windows service project C#. I want to using static method of A1 project, from windows service project. Of course i added reference but i can't access that method. That method does access to Couchbase(Nosql).For example: Create, Insert, Update etc... If you have some experience, please help me.
class Trigger_class // this class in windows service project
{
static double scheduledHour = 12;
static double scheduleMinute = 42;
static DateTime scheduleTime;
//static TimeSpan _ScheduledRunningTime = new TimeSpan(16,00,00);
System.Timers.Timer Timer = null;
double interval = 10;
public Trigger_class()
{
scheduleTime = DateTime.Today.AddHours(scheduledHour).AddMinutes(scheduleMinute);
}
public void Start()
{
Timer = new System.Timers.Timer(interval);
Timer.AutoReset = true;
Timer.Enabled = true;
Timer.Start();
Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
if (scheduleTime < DateTime.Now)
{
scheduleTime = scheduleTime.AddHours(24);
mix_plan.computeNextDayPlan(); // <-- This is A1's static method
}
I'm making a WPF application to simulate traffic. I want the Cars to have a reaction delay of 1 second befor changing their acceleration, without stopping the whole application. To do so, I want to acces the elapsed variable from my Car class. The elapsed variable stores how much time has passed.
The code in MainWindow:
namespace TrafficTester
{
public partial class MainWindow : Window
{
Timer timer = new Timer();
public MainWindow()
{
InitializeComponent();
//create the timer
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Interval = timerInterval;
timer.Enabled = true;
//...
void OnTimedEvent(object source, ElapsedEventArgs e)
{
timer.Enabled = false; //stop timer whilst updating, so updating won't be called again before it's finished
update(); //
timer.Enabled = true;
elapsed += timerInterval;
}
}
}
The code in the Car class:
namespace TrafficTester
{
public class Car
{
//...
public void changeAccel(double val)
{
int time = MainWindow.elapsed;
int stop = MainWindow.elapsed + reactDelay;
while (time < stop)
{
time = MainWindow.elapsed;
}
accel = val;
}
}
}
accel is the current acceleration and val is the new acceleration. MainWindow.elapsed should call the elapsed variable from MainWindow, but it doesn't. How can I call it from the Car class?
I saw at least 2 problems:
- If you want to access the timer intance, it needs to be public.
- Then you can access it via an instance of your Mainwindow.
To get the elapsed time, like you probably want, you need to go from you ElapsedEventHandler and do the timing action there!
public partial class MainWindow : Window
{
public System.Timers.Timer myTimer = new System.Timers.Timer();
public MainWindow()
{
//create the timer
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); // Where is it?
myTimer.Interval = 5;
myTimer.Enabled = true;
}
//...
void OnTimedEvent(object source, ElapsedEventArgs e)
{
myTimer.Enabled = false; //stop timer whilst updating, so updating won't be called again before it's finished
//update(); //
myTimer.Enabled = true;
// Timer.Elapsed += 5;
}
}
public class Car
{
public void changeAccel(double val)
{
var myWin = (MainWindow)Application.Current.MainWindow;
int time = myWin.myTimer.Elapsed; //<-- you cannot use it this way
}
}
I am new to C# but java has method to execute specified task at the specified time so using c# how it doing
Timer t=new Timer();
TimerTask task1 =new TimerTask()
t.schedule(task1, 3000);
You can get a complete tutorial of how timer works in C# here : http://www.dotnetperls.com/timer
In Short:
using System;
using System.Collections.Generic;
using System.Timers;
public static class TimerExample // In App_Code folder
{
static Timer _timer; // From System.Timers
static List<DateTime> _l; // Stores timer results
public static List<DateTime> DateList // Gets the results
{
get
{
if (_l == null) // Lazily initialize the timer
{
Start(); // Start the timer
}
return _l; // Return the list of dates
}
}
static void Start()
{
_l = new List<DateTime>(); // Allocate the list
_timer = new Timer(3000); // Set up the timer for 3 seconds
//
// Type "_timer.Elapsed += " and press tab twice.
//
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true; // Enable it
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_l.Add(DateTime.Now); // Add date on each timer event
}
}
Using Anonymous Methods and Object Initializer:
var timer = new Timer { Interval = 5000 };
timer.Tick += (sender, e) =>
{
MessageBox.Show(#"Hello world!");
};
Here is a sample:
public class Timer1
{
public static void Main()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 5 seconds.
aTimer.Interval=5000;
aTimer.Enabled=true;
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read()!='q');
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("Hello World!");
}
}
using System;
using System.Threading;
namespace ConsoleApplication6
{
class Program
{
public void TimerTask(object state)
{
//Do your task
Console.WriteLine("oops");
}
static void Main(string[] args)
{
var program = new Program();
var timer = new Timer(program.TimerTask,
null,
3000,
Timeout.Infinite);
Thread.Sleep(10000);
}
}
}
ok so i have two classes each with timers set at different intervals. one goes off every 2 seconds, the other every 2 minutes. each time the code runs under the timer i want it to raise an event with the string of data the code generates. then i want to make another class that subscribes to the event args from the other classes and does something like write to console whenever an event is fired. and since one class only fires every 2 minutes this class can store the last event in a private field and reuse that every time until a new event is fired to update that value.
So, how do i raise an event with the string of data?, and how to subscribe to these events and print to screen or something?
this is what i have so far:
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
}
}
}
}
First, I would make a base class that has handles the logic relating to the event. Here is an example:
/// <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));
}
}
That class declares a custom EventArgs class to expose the string value and a helper method for raising the event. Once you update your timers to inherit from that class, you'll be able to do something like:
RaiseEvent(aida.ToString());
You can subscribe to these events like any other event 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);
}