I am going to create a system service in C#.
In the onstart section I would like to loop every 30 seconds and query a mysql database. If numrows are greater than 0 I will process some faxes using the faxcom library.
My question is: Would looping every 30 seconds exhaust the program/computer? What would be the best function/method to use for the loop and sleep? Do you have any example code for the loop and sleep?
Using Thread.Sleep() would be a bad solution, because even while sleeping your thread is active. Use Timer class instead and handle its Elapsed event.
This article examines different ways to tackle the periodical execution of your service.
Here is what your OnStart method might look like:
using System.Timers;
private timer = new Timer();
protected override void OnStart(string[] args)
{
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 30000; // every 30 seconds
timer.Enabled = true;
}
Private void OnElapsedTime(object source, ElapsedEventArgs e)
{
// Execute your code here
}
I wouldn't use looping constructs for such a thing.
I would use one of the timer controls in the BCL and set it to fire every 30 seconds.
As for the question of if this is "too much", the answer entirely depends on the amount of work being done and the load it generates.
No, you would not be using the CPU, because sleeping threads are not scheduled for execution until their sleep time expires. Use Thread.Sleep to make the current thread sleep for timeout miliseconds. Something like:
while(!stop) // boolean variable to indicate when to stop the service.
{
Thread.Sleep(30000);
// do work
}
You will, of course, need to run this on a separate thread, otherwise you will block the main thread.
I would avoid using System.Timers.Timer in your case solely because you are writing a Windows Service. While you can use it, you won't have a GUI available and therefore don't need anything that this timer would expose as if you were using a GUI (it inherits from System.ComponentModel.Component for this reason). It's pretty simple
to use.
Related
How to schedule the event, for instance I need to call a method which should perform its action for every given seconds. I'm developing simple windows form app, I tried using like
while(true)
{
methodToBeScheduled();
Thread.Sleep(60000);
}
This particular piece of code makes my application "Not-responding" while its executing. I hope timer can do this or any other logic that you experts suggest, kindly please let me know.
Thanks!
You can use the WinForms timer:
Timer _timer;
// In constructor (or anywhere you want to start the timer, e.g. a button event):
_timer = new Timer();
_timer.Interval = 60000; // milliseconds
_timer.Tick += (sender, e) => methodToBeScheduled();
_timer.Start();
This will cause methodToBeScheduled to be called once every 60 seconds, roughly. It will be called on the main UI thread, so avoid doing any heavy processing in it.
The advantage of using this timer is that it's built-in, doesn't require thread synchronization, and is simple to use. The disadvantage is that the interval is not exact -- the actual interval will vary depending on what other messages need to be processed in the application, and is also at the mercy of the Windows system clock, which is only accurate to 10-20ms or so.
You can use a Timer(System.Threading.Timer).
using System;
using System.Threading;
Timer _timer = null;
_timer = new Timer(o =>
{
methodToBeScheduled();
});
_timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(60));
Var sequence = Observable.interval(1).publish
Sequence.subscribe ....
Will allow to subscribe to an observable that will fire an onnext every second. See reactive extension ..
Hate typing on iPads....
Yes, there are three different types of timers (all of which are named Timer but behave a little different) in .net. The windows.forms timer executes a function at a certain rate--it calls the function from the UI thread. The System.Threading Timer does the same but calls the function from another thread. There is another timer that I can't remember off the top of my head. You will have to pick one of them based on your circumstance.
Threading timer is my favorite. Here is an example if how to use it. Just keep in mind whatever you are calling is not done from the UI thread. May want to use the forms timer or synchronize things if that's an issue.
I'm really struggling with this. I'm creating a winforms application in visual studio and need a background timer that ticks once every half hour - the purpose of this is to pull down updates from a server.
I have tried a couple of different approaches but they have failed, either due to poor tutorial/examples, or to my own shortcomings in C#. I think it would be a waste of time to show you what I have tried so far as it seems what I tried was pretty far off the mark.
Does anyone know of a clear and simple way of implementing an asynchronous background timer that is easily understandable by a C# newbie?
// Create a 30 min timer
timer = new System.Timers.Timer(1800000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
...
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// do stuff
}
with the usual caveats of: timer won't be hugely accurate and might need to GC.KeepAlive(timer)
See also: Why does a System.Timers.Timer survive GC but not System.Threading.Timer?
Declare member variable in your form:
System.Timers.Timer theTimer;
On form load (or whatever other time you need to start update polling), do:
theTimer = new System.Timers.Timer(1800000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();
Declare your PollUpdates member function like this:
private void PollUpdates(object sender, EventArgs e)
{
}
I think you need to know about all timer classes. See Jon's answer below.
What kind of timer are you using?
System.Windows.Forms.Timer will execute in the UI thread
System.Timers.Timer executes in a thread-pool thread unless you
specify a SynchronizingObject
System.Threading.Timer executes its callback in a thread-pool thread
In all cases, the timer itself will be asynchronous - it won't "take up" a thread until it fires.
Source: Do .NET Timers Run Asynchronously?
I'm writing a windows service to execute some method every x minutes, but I want the method to execute synchronously relative to the timer itself. The windows service have a Timer object (System.Timers.Timer) which starts and calls some method 'DoWork' every x minutes, but the timer must 'stop' while 'DoWork' is executing and starts again after the method is finished.
I'm aware that using the System.Windows.Forms.Timer class would give me the behavior I want, but I don't want to add a System.Windows.Forms dll reference to my Service project.
Here is an example of 'working' code:
private System.Timers.Timer timer1;
public void MainMethod()
{
timer1 = new System.Timers.Timer();
timer1.Interval = 1000;
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
timer1.Start();
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
timer1.Stop();
DoWork();
timer1.Start();
}
private void DoWork()
{
Thread.Sleep(2000);
Console.WriteLine("found!");
}
Running above in a console application (as a mockup before writing the windows service), the expected behavior should be for the console to write 'found!' every 3 seconds.
Just a side-note: I'm just using 'Thread.Sleep(2000)' to mimic a delay but it won't form part of the actual code base.
Is there any other / "better" way to achieve this than my way above?
Thanks for reading my question and any input would be greatly appreciated.
You can't use System.Forms.Timer in a windows service because that would require a message pump and Windows services are not given a message pump stack that can be very large (plus you'd have to call Application.Run to start one).
The way you have it now is the way I implement periodic events. I'd add something to monitor whether your events take longer than the period; but other than that...
I think it depends on whether you just want the X second delay between calls to the method to be a constant, or if you'd like the method to be called every X seconds, but with allowances if the method takes longer than X seconds to execute.
Your code above will do the former, where there's a one second delay between method calls, but if you want your method to be called every X seconds, you may want to consider using timestamps with DateTime.Now and DateTime.Subtract to see if a suitable time has passed since the last method call. This may cause unusual behaviour if the system clock gets changed, such as at daylight saving time where the method may not run for an hour but this unusual behaviour may be deemed acceptable to you in your situation.
It seems that the main problem you are having is described as " the timer must 'stop' while 'DoWork' is executing and starts again after the method is finished" .In short, the service needs to be multi-threaded. You should consider using a thread pool. Using a thread pool will allow your executing thread to continue counting time will a background thread does some other work. Check out the ThreadPool docs here: http://msdn.microsoft.com/en-us/library/3dasc8as%28v=vs.80%29.aspx .
I'm writing a windows service that should perform an action every, lets say, 60 seconds.
How is the best way to implement that main loop?
Implementations I've seen so far:
1) Using a Timer object that executes a delegate every xx seconds
2) Using ManualResetEvents (the implementation I've seen only executes once, but as far as I understood, it is possible to create a loop with such resetevents)
The windows service will run all the time, so it would be best to create a service that has no memory leak.
What is the best way to implement that main loop?
Edit after comments:
The action that will be performed every X seconds will start several (lets say max 10) threads. Each thread does not run longer than 30 seconds
Use a Timer. This will make the intention of the program the most clear. It is easy to start and stop the timer from your OnStart and OnStop methods, and the callbacks will fire on the thread pool so you won't tie up a thread. The Timer object won't leak memory by itself. (You could still write a bug that leaks memory, but that's equally easy to do with any implementation of the main loop.)
Consider using Quartz.net. I'm using this library and I'm very happy with it. You could set custom cron schedule that will suit your needs.
If you do use a system.timers.timer make sure to set autoreset to false and start it and the end of your process. Here's a full example
Needed: A Windows Service That Executes Jobs from a Job Queue in a DB; Wanted: Example Code
If there is no chance that your action will not ever take longer than xx seconds I would just go with the timer. If not I would go with the ManualResetEvents. I assume you do not want more than one action to run concurrently.
Here is another pretty common pattern using a ManualResetEvent as both a stopping and a throttling mechanism.
public class Example
{
private Thread m_Thread;
private ManualResetEvent m_StopSignal = new ManualResetEvent(false);
public void Start()
{
m_Thread = new Thread(Run);
m_Thread.Start();
}
public void Stop()
{
m_StopSignal.Set();
if (!m_Thread.Join(MAX_WAIT_TIME))
{
m_Thread.Abort() // Abort as a last resort.
}
}
private void Run()
{
while (!m_StopSignal.WaitOne(YOUR_INTERVAL))
{
// Your task goes here.
}
}
}
I'm hoping someone can shed some light on what might be happening for me. Here's a summary of whats happening.
I have an application that does lots of "stuff". Its a pretty hefty application that does lots of number crunching using many threads. There are several timers that are used. Over a long period of time, the timers stop consistently invoking the elapsed handler.
For instance: I have a timer set to elapse every second. After a period of hours the timer starts randomly triggering late. If I do not restart the application the performance just degrades and the timers fire later and later eventually turning into 3 or 4 seconds, forcing me to restart the application. I have not been able to identify any leaks. CPU usage does not go up, memory does not go up, and the server is no where near being maxed out. Can anyone give me some ideas as to what may be causing this?
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if (seconds > 0)
{
seconds--;
timer.Start();
}
}
Is it possible you're exhausting the thread pool? Most timers invoke the handler using a threadpool thread. If all threadpool threads are in use, it will just get queued until one is available.
If that's the case switch some of your processing to use your own threads, not threadpool threads.
To test if you're exhausting the thread pool start up a background thread that periodically (a few times a second) checks ThreadPool.GetAvailableThreads and logs a message when the available is small (even if it's never actually zero when you check, if it sometimes approaches zero then it's likely this is the problem).
The size of the pool can be changed with ThreadPool.SetMaxThreads although that may not be the best solution. If you're using threadpool threads for longer running tasks, stop it. For long-running tasks use your own threads.
the timer class you use is really important
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
but I don't think the problem is the timer itself,
for instance try making an application using the same timer class
that ONLY writes the current DateTime to a log file
and leave it running for an extremely long period of time, you'll see that there's no such a 3/4 seconds delay
review your timer code and check that no shared resources are being accessed at the same time,
maybe the Timer is OK, but there's a bottleneck in the event handler function or in "something" that function uses
Sounds like maybe it's not really the same timer, and so the resources being "leaked" here are GDI handles.
Possible workaround:
DateTime mayContinue = DateTime.MinValue;
bool blockingUi = false;
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if( blockingUi )
{
if( DateTime.Now < mayContinue )
{
// Notify time remaining
// Update the UI with a BeginInvoke
}
else
{
blockingUi = false;
// Notify ready
// Update the UI with a BeginInvoke
}
}
}
private void BlockUi()
{
mayContinue = DateTime.Now.AddSeconds(30);
blockingUi = true;
}