How to repeat it at every X intervals? - c#

on Get Property i am checking for DNS LookUp
But it is only executed at startup only..How to execute it at every X intervals
System.Net.IPHostEntry ipHe = System.Net.Dns.GetHostByName("www.google.com");
return (#"Images/online.png");

I'm making a lot of assumptions here, but I assume you are talking about keeping a WPF form updated with an "online" status that has an auto-refresh feature? And doing so in the MVVM model.
If those assumptions are right, in your view model you can use a System.Timers.Timer that will fire at any Interval you specify, and it can execute any method you specify by hooking into its Elapsed event.
public class ViewModel{
private static System.Timers.Timer aTimer;
public ViewModel()
{
aTimer = new Timer();
aTimer.Interval = 2000; // every two seconds
// Hookup to the elapsed event
aTimer.Elapsed += DoWork;
// Have the timer fire repeated events (true is the default)
aTimer.AutoReset = true;
// Start the timer
aTimer.Enabled = true;
}
public void DoWork(Object source, System.Timers.ElapsedEventArgs e) {
//do work here
}
}

Related

.Net: how to wait until System.Timers.Timer stops

I have a System.Timers.Timer instance created in the main thread. Now I call timer.Stop() to try to terminate that time and want to wait until the timer is really terminated. How could I do that?
Is there any similar method like System.Threading.Thread.Join()?
Here are some codes
//the main thread:
var aTimer = New Timer();
aTimer.Elapsed += SomeTimerTask;
aTimer.AutoReset = True;
aTimer.Start();
//some other logic...
//stop that timer:
aTimer.Stop();
//now I need to wait until that timer is really stopped,
//but I cannot touch the method SomeTimerTask().
//so I need something like System.Threading.Thread.Join()...
You could make use of a ResetEvents which are wait handles which can block a thread until you set the state to signaled:
class TimerAndWait
{
private ManualResetEvent resetEvent = new ManualResetEvent(false);
public void DoWork()
{
var aTimer = new System.Timers.Timer(5000);
aTimer.Elapsed += SomeTimerTask;
aTimer.Elapsed += ATimer_Elapsed;
aTimer.AutoReset = true;
aTimer.Start();
// Do something else
resetEvent.WaitOne(); // This blocks the thread until resetEvent is set
resetEvent.Close();
aTimer.Stop();
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
resetEvent.Set();
}
}
If you want a async/task-based solution you have to use the ThreadPool.RegisterWaitForSingleObject method
The Timer does not fire up the Elapsed when you call stop as you can read in the docs of the Stop()-Method:
Stops raising the Elapsed event by setting Enabled to false.
The Elapsed-Event is only triggered when the Timers Enabled-Property is set to true and the given Interval (which you have to set) is elapsed (this can happen multiple times).
So if you stop your Timer before the Interval is elapsed, you might have to trigger your code in some other way.

c# timer.elapsed?

I have included the System.Timers package, but when I type:
Timer.Elapsed; //its not working, the property elapsed is just not there.
I remember it was there in VB.NET. Why doesn't this work?
It's not a property. It's an event.
So you gotta provide an event handler that will execute every time the timer ticks. Something like this:
public void CreateTimer()
{
var timer = new System.Timers.Timer(1000); // fire every 1 second
timer.Elapsed += HandleTimerElapsed;
}
public void HandleTimerElapsed(object sender, ElapsedEventArgs e)
{
// do whatever it is that you need to do on a timer
}
Microsofts example.
http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx
Elapsed is an event and therefore requires an eventhandler.
using System;
using System.Timers;
public class Timer1
{
private static System.Timers.Timer aTimer;
public static void Main()
{
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
/* This code example produces output similar to the following:
Press the Enter key to exit the program.
The Elapsed event was raised at 5/20/2007 8:42:27 PM
The Elapsed event was raised at 5/20/2007 8:42:29 PM
The Elapsed event was raised at 5/20/2007 8:42:31 PM
...
*/
The previous answers here are all correct, however with .net 6 / VS2022 now out and about nullability is big deal, and all the above answers will throw compiler warning CS8622.
The solution to this is to simply mark the source object as nullable in your callback function's parameters, like such:
...
var timer = new System.Timers.Timer(2000); // every 2000ms
timer.Elapsed += TimerElapsedHandler;
...
public void TimerElapsedHandler(object? source, ElapsedEventArgs e)
{
//Your Handling Code Here
}
You need an event handler, then after Enabling while assigning event handler and stop in your handler a condition
Timer = new System.Timers.Timer();
Timer.Elapsed += new System.Timers.ElapsedEventHandler(PageLoaded);
Timer.Interval = 3000;
Timer.Enabled = true;
...................
public void PageLoaded(object source, System.Timers.ElapsedEventArgs e)
{
// Do what ever here
if (StopCondition)Timer.Enabled = false;
}

How do I show text on a label for a specific time (like 3 seconds)?

I have a statusbar label and I want to show a text on my StatusBar Label for 3 seconds only
How can I do it without using threads?
public void InfoLabel(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(InfoLabel), new object[] { value });
return;
}
infoLabel.Text = value;
}
Simply add timer on the end of your method:
if (!string.IsNullOrWhiteSpace(value))
{
System.Timers.Timer timer = new System.Timers.Timer(3000) { Enabled = true };
timer.Elapsed += (sender, args) =>
{
this.InfoLabel(string.Empty);
timer.Dispose();
};
}
You need to define a function that you call each time you need to display your text, inside this function you define a timer, this timer is based on System.Windows.Forms.Timer, the only difference is that its modified to hold a stopTime parameter that represents the running duration, the only thing you need to do is to put your starting code(display text) inside the MyFunction function and to put the ending code(to stop displaying text) inside the Timer_Tick function, once you call MyFunction just specify how many seconds you want it to run in the function parameter.
private void MyFunction(int durationInSeconds)
{
MyTimer timer = new MyTimer();
timer.Tick += new EventHandler(Timer_Tick);
timer.Interval = (1000) * (1); // Timer will tick every second, you can change it if you want
timer.Enabled = true;
timer.stopTime = System.DateTime.Now.AddSeconds(durationInSeconds);
timer.Start();
//put your starting code here
}
private void Timer_Tick(object sender, EventArgs e)
{
MyTimer timer = (MyTimer)sender;
if (System.DateTime.Now >= timer.stopTime)
{
timer.Stop();
//put your ending code here
}
}
the modified timer class
public class MyTimer : System.Windows.Forms.Timer
{
public System.DateTime stopTime;
public MyTimer()
{
}
}
You can use Timer to create an instance of a timer that waits for n seconds before firing the Elapsed event. In the elapsed event, you clear the label's Content.
As the timer is executed in a separate thread, the UI thread is not locked while the timer is counting i.e. you are free to perform other operations in the UI.
private delegate void NoArgDelegate();
private void StartTimer(int durationInSeconds)
{
const int milliSecondsPerSecond = 1000;
var timer = new Timer(durationInSeconds * milliSecondsPerSecond);
timer.Start();
timer.Elapsed += timer_Elapsed;
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
var clearLabelTextDelegate = new NoArgDelegate(ClearLabelText);
this.Dispatcher.BeginInvoke(clearLabelTextDelegate);
}
private void ClearLabelText()
{
this.myLabel.Content = string.Empty;
}
As I do not the rest of your code, some suggestions would be to create a lock on the timer so as to prevent more than one UI event starting the timer. In addition, the delegate and the timer instance can be made as private members of the class.
You'll always be using at least the GUI thread. If you decide to wait on that thread, no other interaction with controls is possible (ie. no buttons will work, the window will not be repainted).
Alternatively you could use a System.Windows.Forms.Timer that gives control back to the OS, or another type of timer. Either way, the "countdown" will either block user interaction or happen on another thread (under the hood).

Fire timer_elapsed immediately from OnStart in windows service

I'm using a System.Timers.Timer and I've got code like the following in my OnStart method in a c# windows service.
timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Interval = 3600000;
timer.Start();
This causes the code in timer_Elapsed to be executed every hour starting from an hour after I start the service. Is there any way to get it to execute at the point at which I start the service and then every hour subsequently?
The method called by timer_Elapsed takes too long to run to call it directly from OnStart.
Just start a threadpool thread to call the worker function, just like Timer does. Like this:
timer.Elapsed += timer_Elapsed;
ThreadPool.QueueUserWorkItem((_) => DoWork());
...
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
DoWork();
}
void DoWork() {
// etc...
}
Use AutoReset Property of System.Timers.Timer and set it value to "true".
No need to use timer.Start() because it does the same job as timer.Enabled = true;
timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Interval = 3600000;
timer.AutoReset = true;
AutoReset = true will set a value indicating that the Timer should raise the Elapsed event each time when the specified interval elapses.
If you want your Timer to be fired immediately then you could simply just initialize the Timer object without a specified interval (it will default to 100ms which is almost immediately :P), then set the interval within the called function to whatever you like. Here is an example of what I use in my Windows Service:
private static Timer _timer;
protected override void OnStart(string[] args)
{
_timer = new Timer(); //This will set the default interval
_timer.AutoReset = false;
_timer.Elapsed = OnTimer;
_timer.Start();
}
private void OnTimer(object sender, ElapsedEventArgs args)
{
//Do some work here
_timer.Stop();
_timer.Interval = 3600000; //Set your new interval here
_timer.Start();
}
Use System.Threading.Timer class instead of System.Timers.Timer as this type is just a wrapper for Threading Timer.
It also suits your requirement.
System.Threading.Timer timer =
new System.Threading.Timer(this.DoWork, this, 0, 36000);
Here are the details.

How to stop a timer after it is done running?

I have a Console App and in the main method, I have code like this:
Timer time = new Timer(seconds * 1000); //to milliseconds
time.Enabled = true;
time.Elapsed += new ElapsedEventHandler(time_Elapsed);
I only want the timer to run once so my idea is that I should stop the timer in the time_Elapsed method. However, since my timer exists in Main(), I can't access it.
You have access to the Timer inside of the timer_Elapsed method:
public void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Timer timer = (Timer)sender; // Get the timer that fired the event
timer.Stop(); // Stop the timer that fired the event
}
The above method will stop whatever Timer fired the Event (in case you have multiple Timers using the same handler and you want each Timer to have the same behavior).
You could also set the behavior when you instantiate the Timer:
var timer = new Timer();
timer.AutoReset = false; // Don't reset the timer after the first fire
A little example app:
static void Main(string[] args)
{
int seconds = 2;
Timer time = new Timer(seconds * 1000); //to milliseconds
time.Enabled = true;
time.Elapsed += new ElapsedEventHandler(MyHandler);
time.Start();
Console.ReadKey();
}
private static void MyHandler(object e, ElapsedEventArgs args)
{
var timer = (Timer) e;
timer.Stop();
}
I assume that you're using System.Timers.Timer rather than System.Windows.Forms.Timer?
You have two options.
First, as probably the best, is to set the AutoReset property to false. This should do exactly what you want.
time.AutoReset = false;
The other option is to call Stop in the event handler.
You may also use the System.Threading.Timer. Its constructor takes two time-related parameters:
The delay before the first "tick" (due time)
The period
Set the period to Timeout.Infinite to prevent from firing again.

Categories