I am creating windows service. I want to run the service every 30 seconds.
So I have used timer on windows service start using the following code.
protected override void OnStart(string[] args)
{
timer1 = new Timer();
timer1.Interval = 30000;
timer1.Elapsed += new ElapsedEventHandler(timer1_tick);
timer1.Start();
}
In timer1_tick function, I am performing some actions like updating user details, uploading and downloading files.
But here I am not sure that the above action will finish within 30 seconds.
So I want to run one at a time.
Here timer1_tick function called every exact 30 seconds. This should be happen only if the timer1_tick function finishes every task.
How to do that?
You should stop the timer and wait for the uploading and downloading of files to finish using Timer.Stop(); and Timer.Start():
void timer1_tick(...){
timer1.Stop();
//Do your download, upload, etc.
timer1.Start();
}
Hope it helps!
As per your requirement use Asynchronous Programming. It might be help you. Thank You
timer1.Elapsed += new ElapsedEventHandler(await timer1_tick);
async Task<void> timer1_tick()
{
//Do your download, upload, etc.
}
Related
I have a windows service that archives files from a paticular folder. I want the program to run everday at a specific time. I can do that using the task scheduler. what I want to do is to schedule the task without actually assessing the windows task scheduler GUI. Maybe a batch script that schedules the program to run every day even when the system is on sleep or maybe something else i can do?
does anyone have an idea of how this thing can be implemented?
The solution is pretty basic . so the thing is that instead of using the task scheduler we are creating a scheduler itself in our code so there is a thread that will be created that will always be checking for the time that I want my actual code to run and once the current time is the time that I want the method to run it will trigger the main program(in the example the method I want to trigger is named ArchiveFile) .
so first in the OnStart I am setting a new timer and want it to fire 24x7,every hour.
then in the timer_elapse i want to check if the current time is the time I want my method to execute and if true it will call the method that I want to execute.(in this example I have set the time to be 9 pm or 21 hours)
protected override void OnStart(string[] args)
{
timer = new System.Timers.Timer();
timer.Interval = 36000; // that fires every hour
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); //calling the elapse event when the timer elapses
timer.AutoReset = true; // AutoReset is set to true as we want the timer to fire 24x7 so that the elapse event is executed only at the requried time
timer.Enabled = true;
}
protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) //everytime the elapse event occurs the TimeCheck method will be called
{
TimeCheck();
}
public void TimeCheck() //method to check if the current time is the time we want the archiving to occur
{
var dt = DateTime.Now.Hour;
if(dt==21)
{
Archivefile();
}
}
I wrote little service that check some folder every minute and send the content to FTP folder. inside the service in OnStart method i sets timer for event that runs every minute:
protected override void OnStart(string[] args)
{
aTimer = new Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 60000;
aTimer.Enabled = true;
}
The Event:
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
some logic here....
}
Now my question: is that ok to invoke onStart method only once and let the event do the rest? or should i run onStart method every minute instead of event?
Your application logic which runs every minute, should be inside the event OnTimedEvent.
Read more in Microsoft Documentation here which gives a walkthrough on how to create a Windows Service Application: MS Docs - Walkthrough: Create a Windows service app
is that ok to invoke onStart method only once and let the event do the rest?
Yes, OnStart should be executed only once, which is when your service is started.
or should i run onStart method every minute instead of event?
No, OnStart should run only once.
Suggestion: You might want to increase the time interval, if you are expecting a lot of files or if the file size is going to be large.
I've try searching in this website ways to display date and time. But all the example here shows only static date and time. Is there a way to display date and time which is running or I should say increment every second? Does it involve updating the time every second?
Use a timer object and in the tick event show the date in the textbox
in winforms use
System.Windows.Forms.Timer tmr = null;
private void StartTimer()
{
tmr = new System.Windows.Forms.Timer();
tmr.Interval = 1000;
tmr.Tick += new EventHandler(tmr_Tick);
tmr.Enabled = true;
}
void tmr_Tick(object sender, EventArgs e)
{
myTextBox.Text = DateTime.Now.ToString();
}
You can add a Timer to your form. Set it to fire once per second. In the event handler for your timer, update the text box with the current time.
You're right in your second option.
It's all about using a timer and update TextBox with current time.
Use a timer with an interval of 1 second. If your app is winforms, use timer from windows.forms namespace http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx , it runs in the same thread as gui, so it is safe to update gui. You also can use timer from system.threading namespace, but in this case you should update controls in thread-safe manner by calling invoke method http://msdn.microsoft.com/en-us/library/ms171728.aspx. If your app is web, use javascript instead
There is a Delay method in Task, which takes milliseconds as an input. For me the code for the Time update is like as below,
Using System.Threading.Tasks;
async void TimeUpdater()
{
while (true)
{
TxtTime.Text = DateTime.Now.ToString();
await Task.Delay(1000);
}
}
This will update the UI and wait for 1 Second and then again iterate over, for infinite times. Also don`t forget to make the method async, because of the await operator. As I`ve researched this is the easiest method to get a running date and time in the UI weather WinForms or WPF.
I have a program written in C# (Visual Studio), that works on a tray.
I want it to do one action every 10 minutes.
I have following code now:
while(true)
{
Thread.Sleep(10000);
// my stuff
}
But it doesn't work. It freezes a program.
You should use the timer object and not create a while loop.
System.Timers.Timer _timer = new System.Timers.Timer();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
//30 seconds
_timer.Interval = 30000;
_timer.Start();
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//do your logic
}
Thread.Sleep makes the calling thead Sleep for an X ammount of time. If this thread is the frontend thread (the one responsible for handling messages), it will indeed freeze the application since any message for handling events or repainting wont be handeled untill the Thread wakes up again and gets a chance of handling the messages.
What you should do is schedule this logic every 10 seconds.
Drop a timer on your form and specify it to run each 10 seconds. Within the Tick event, call your custom action.
Thread.Sleep "stops" the current thread. if you only have one thread, everything is paused.
What do you want to achieve ?
Perhaps you need a second thread, or perhaps the better solution a timer which triggers a action every 10 minutes
s. Task.StartNew() or ThreadPool
I have an issue with the System.Timers.Timer object. I use the timer object to perform a task at regular intervals. In the timer constructor I call the method doing the work ( DoTimeCheck() ), to ensure that the task is run once at startup also. The work (at regular intervals) is done in a BackgroundWorker.
I call the timer with this:
UpdaterTimer ut = UpdaterTimer.UpdaterTimerInstance;
My problem is that I need to delay the first run of the task with 3 minutes(the one that runs at application startup). Subsequent runs (Elapsed event) should run without delay. I thought of doing this by calling
System.Threading.Thread.Sleep(TimeToDelayFirstRunInMiliseconds);
but this fails, because it also hangs the UI of the app (main thread) making it unusable. How can I delay the first run of DoTimeCheck() without hanging the UI?
The code of the timer is below. If the issue is not presented in a clear manner please let me know and I will edit. Thank you in advance.
public sealed class UpdaterTimer : Timer
{
private static readonly UpdaterTimer _timer = new UpdaterTimer();
public static UpdaterTimer UpdaterTimerInstance
{
get { return _timer; }
}
static UpdaterTimer()
{
_timer.AutoReset = true;
_timer.Interval = Utils.TimeBetweenChecksInMiliseconds;
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
DoTimeCheck();
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
DoTimeCheck();
}
private static void DoTimeCheck()
{
//... work here
}
}
One way of doing this would be to give the Timer Interval an initial value (e.g. 3 minutes). Then, in your Elapsed event handler, you could change the interval to your regular value which will be used from then on.
_timer.Interval = Utils.InitialCheckInterval;
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (_timer.Interval == Utils.InitialCheckInterval)
{
_timer.Interval = Utils.RegularCheckInterval;
}
DoTimeCheck();
}
It appears (although you've not shown that code) that you're calling Sleep(TimeToDelayFirstRunInMiliseconds); on the main/GUI thread, so that's what's causing your UI thread to hang. Instead, you should set your timer to be delayed by 3 minutes on the first run, then once it runs you change the timer again to run at the frequency you desire for all the subsequent runs.
Your UI resides on the same thread, so when you put the thread to sleep, it will cause your UI to hang as well. You need to run the timer on a different thread.
You're already using timers fine it seems. Just use another one to do a three minute delay before you start up your other timer.
timer = new Timer();
timer.AutoReset = false;
timer.Interval = 3*60*1000;
timer.Elapsed += startOtherTimerMethod;
timer.Start();
Edit: I should note that this is much the same as Peter Kelly's answer except that his solution is more elegant since it uses just one timer, no extra methods and takes advantage of the fact that the timer is changeable between runs. If you liked this answer, you'll love his. ;-)
Your UI needs a seperate thread, currently you are also sleeping the UI. Check this post.
You should not use thread.sleep in this situation you should use the winforms control
BackgroundWorker which never locks the main UI. You can write your logic there.
example here:
http://www.knowdotnet.com/articles/backgroundworker.html
Use a System.Threading.Timer - the constructor takes a parameter for the delay of the first run and an interval for the subsequent runs.