Sort of scheduler - c#

I need to implement something. Something that could do some certain task in my program. For example every ten seconds, write something into a log in a file.
Of course it suppose to run in a background thread.
Where should I dig? I am not so familiar with multithreading. I've heard about BackgroundWorker class, but I'm not sure if it is appropriate here..

Use System.Threading.Timer, it will run a task in a ThreadPoool thread. That is the most efficient way for this.
Here is an example, every 10 seconds:
Timer aTimer = new System.Threading.Timer(MyTask, null, 0, 10000);
static void MyTask(object state)
{
...
}

Actually for WPF DispatcherTimer would be much better than the Async timer.

You could use the backgroundworker class for this, but it sounds like you just need to use Timer.

Related

how to recalculate something ~once per second?

I need to do some pretty fast recalculation ~every second.
What is the best way to do that? Is using dedicated thread and Thread.Sleep is ok?
Task.Factory.StartNew(() =>
{
while (true)
{
RecalculateState();
Thread.Sleep(1000);
}
}, TaskCreationOptions.LongRunning);
That would work - but another alternative would be to use a timer, e.g. System.Threading.Timer or System.Timers.Timer.
You should think about:
What do you want to happen if it takes more than a second to recalculatte state?
Is your RecalculateState method entirely safe to be called from arbitrary threads?
You can use System.Timers.Timer with 1 second interval.
It already runs in a new thread .
Pay attention on fact, that if RecalculateState runs longer than expected interval (for 1000 of reasons) you have to deal with calls overlapping, so you have to manage that case in some way.
One of possible solutions, is to run a new code only after execution of the method finished, and measure difference between execution time and interval. But this is not so easy task to do. Fortunatelly someone already thought about that problem.
Can have a look on Reactive Extensions that in latest build payed special attention on time dependent execution.
Can't you use a timer and make a ontimed event?
Something like this ?
Observable.Timer(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(1)).Timestamp()
.Subscribe(MyOnTimedEventMethod);
I would suggest to use a timer for this.
member:
private readonly Timer _timer;
instantiate the timer in the constructor for instance:
_timer= new Timer(OnTimerEllapsed, null, 0, 1000);
callback:
private void OnTimerEllapsed(object sender)
{
RecalculateState();
}

Alternative to Thread.Sleep in C#?

I have a code which when run, it executes series of lines in sequence.
I would like to add a pause in between.
Currently, I have it like this
//do work
Thread.Sleep(10800000);
//do work
This however freezes the software, and I think it's because sleep time is way too long.
I searched online and I found another work around called Timer.
Can someone show me a sample code for Timer which works just like Thread.sleep?
Thank you in advance.
Edit : I need the software to wait for 3 hours before proceeding with rest of the code execution. This software is meant to communicate with machines, and I cannot let the rest of the code execute while waiting for 3 hours.
Please see this MSDN reference on the System.Threading.Timer class. There is a great explanation, all of the class members, and some sample code for you to follow when testing/learning.
Mind you, though, the Timer should be used when you want to fire an event at a certain interval. If you are just looking to pause execution of your application, then you should go with Thread.Sleep(). However, as many others have pointed out, you are causing your thread to sleep for an extended amount of time.
Your software would freeze if that sleep is on the main thread. Keep in mind the parameter is in milliseconds. 10 800 000 milliseconds = 10 800 seconds
Another way to pass the time is to pass a TimeSpan object instead. Ex:
// Sleep for 10 seconds
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 10));
As for timer:
You can use System.Timers.Timer;
Timer timer = new Timer();
timer.Interval = 20; // milliseconds
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.AutoReset = true; // if not set you will need to call start after every event fired in the elapsed callback
timer.Start();
USE A TIMER!
private DispatcherTimer Timer;
public Constructor
{
Timer = new System.Windows.Threading.DispatcherTimer();
Timer.Tick += new EventHandler(Timer_Tick);
Timer.Interval = new TimeSpan(0,0,10);
Timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
Timer.Stop();
Timer -= Timer_Tick;
Timer = null;
// DO SOMETHING
}
Your problem is that you're blocking the main thread of your application, which is responsible for keeping the ui running. You shouldn't do this. Instead use a timer - the Forms one is probably easiest in a Forms app, or consider BackgroundWorker. (For such a long wait a timer is probably more suitable)
The Thread.Sleep is what you want to use for this, you may want to use a more reasonable sleep period than 3 hours though.
Update:
After reading some of the comments, Thread.Sleep is probably not what you want. Use a System.Threading.Timer instead as others have suggested.
Have a look Thread.Sleep(300) not working correctly
Probably you need to use the "Dispatcher". Have a look here as well
Thread.Sleep would typically be used to pause a separate thread, not in the main thread of your app.
Timer would typically be used to periodically cause the main thread to stop its normal operations and handle an event.
Either method can be used to periodically perform a function after a certain time interval.
What I wouldn't do is ask the main thread to sleep for 3 hours.
I think you should use a Monitor. It helps you to put a wait on objects and release the lock when you need to continue running the program.
You should find your answer here: Safe Thread Synchronization
You can replace
Thread.Sleep(X);
by
Task.WaitAll(Task.Delay(X));
You're sleeping the thread for 10800 seconds, or 3 hours. Thread.Sleep() is designed to freeze your thread, stop anything from working in the software for that duration. In this case, the duration is 18 minutes. What are you trying to do?

Where can I find a good C# console app that demonstrates polling?

I'm looking for a good example of polling in C#.
Basically, every X seconds an instrument is read and the values logged to a text file. I was looking for a sample that makes use of .NET 4's parallel library. Or, maybe I'm overthinking this solution by looking at TPL...
ps- this question is unrelated to my previous question about database polling.
I'm not sure I'd particularly bother with TPL here. Just use System.Threading.Timer or System.Timers.Timer to perform an action periodically. Those will both use the thread pool - what are you planning on doing in the main console thread during this time?
Of course, another extremely simple option would be to just make the main thread sleep between poll occurrences. It's crude, but if that's all your app needs to do, it may well be good enough for you. I'm not sure how it behaves if the system clock is changed, mind you... is this for a very long-running task for production usage, or just a quick tool? (If it's a long-running app, you might want to consider using a Windows Service instead.)
It's real easy to create a timer:
static void Main(string[] args)
{
// Create a timer that polls once every 5 seconds
var timer = new System.Threading.Timer(TimerProc, null, 5000, 5000);
Console.WriteLine("Polling every 5 seconds.");
Console.WriteLine("Press Enter when done:");
Console.ReadLine();
timer.Dispose();
}
static int TickCount = 0;
static void TimerProc(object state)
{
++TickCount;
Console.WriteLine("tick {0}", TickCount);
}
Note that the TimerProc is called on a separate thread. Your main program can do other things, and this will continue to poll every five seconds until you kill (or modify) the timer.
I prefer System.Threading.Timer over System.Timers.Timer because the latter swallows exceptions. If there is a bug in your elapsed event handler that throws an exception, you'll never know about it because the System.Timers.Timer event handler will suppress the exception. For that reason, I strongly suggest that you not use it. Use System.Threading.Timer instead.
Using the PL doesn't sound correct to me for this task. I recommend checking out System.Timer with which you can specify a recurring interval at which the Elapsed event is raised in your application allowing you to handle the event to perform regular processing.

What are the best practices for doing a task after a certain time interval?

I have a Windows Application. We have implemented AutoSave functionality as background process.
Sample code is as below:
While(1)
{
Thread.Sleep(60000) // 1 minute sleep
DoAutoSaveAllControls();
}
I think this is bad functionality. Correct me if I am wrong. But, I want to improve performance and do this task after certain time interval, without doing Sleep.
Also, is it good to do this in background process?
A much better approach would be to use a timer. You can find out about the various different timers in the .NET framework from this excellent article:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
You are using WinForms, so a System.Windows.Forms.Timer will be just fine for you.
For example:
System.Windows.Forms.Timer tmrWindowsFormsTimer = new System.Windows.Forms.Timer();
tmrWindowsFormsTimer.Interval = TimeSpan.FromMinutes(1);
tmrWindowsFormsTimer.Tick += new EventHandler(tmrWindowsFormsTimer_Tick);
tmrWindowsFormsTimer.Start();
private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgs e) {
tmrWindowsFormsTimer.Stop();
DoAutoSaveAllControls();
}
This stops the timer after the first tick, effectively a fire-once timer.
You can use Reactive Extenssions for this as well.It looks more natural and you can combine observables.
var observable = Observable.Timer(
TimeSpan.FromMinutes(1),
TimeSpan.FromMinutes(1)).Timestamp();
using (observable.Subscribe()))
{
DoAutoSave();
}
Thread.Sleep does not affect performance at all. In order to me is perfectly ok, but since your application is probably modifying the document in the UI thread you probably need to sincronize the save in order to avoid concurrent modifications. Just for this reason maybe it would be better to use a Timer instead of BackGroundWorker.
You're right, it's not really a good use of a thread. Take a look at the Timer class.
You can use System.Timers.Timer to start a process after certain interval, check the sample snippet
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(YourHandlerMethod);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
I think you need to trigger save functionality from the calling code (that knows if any changes had already happaned). So that saving thread could know for sure that calling thread has made some changes to save.
This is not an answer for this question, just maybe recommendation. So if you are calling Save from inside of timer, you should verify first if any change happened. To do that you'll need some additional variable, that would be common for working thread and saving thread. If working thread did change something, it triggers that var to true. When saving, if var is true - then saving is needed. After saving - change common var to false.

BackgroundWorker used within collection items

I used a Backgroudworker to do some work in order to do some time consuming tasks.
public void ConnectDataProvider()
{
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
Another method starts the background worker:
public void StartPolling()
{
bgw.RunWorkerAsync();
}
Then I did the event handling:
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do it over again
StartPolling();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
// do work
WriteData();
}
As you can see, I started the worker over on completion. Now this works for a single backgroundworker.
Now I want a collection, and each item should perform this task. However with the concept above it will just keep on running in the first worker started, as it starts the worker over. I'm thinking, maybe a Timer in combination could solve the situation to give the other worker threads way.
Is the BackgroundWorker still a good choice? Is it common to reuse the BackgroundWorker like I did?
EDIT 1: To clairify: The problem I'm facing is, that I need manage the collection each with their own BackgroundWorker. I was thinking about a timer, to set off request periodically from each item. This is where I'm stuck.
EDIT 2: See my own answer, I didn't solve this issue, but found that I can go along with timers to get what I wanted.
EDIT 3: To clarify (another try, I'm not good at that) what I wanted to achieve: I've got tracking objects, for gps tracking. I want to track a whole bunch of them, so one object per tracking device. They all need to be polled frequently. Ihad a BackgroundWorker set up for a single test object. I liked they way the Backgroundworker would tell me when it's done. But I couldn't get it working with all of the tracking objects.
Now every tracking object has its own timer. This timer spawns a new thread and does the time consuming work (which I named DoWrite). No BackgroundWorker needed, as I dispose the timer and then create a new timer. That's all it does.
How many of these might there be? You should be careful of creating a 1:1 relationship between items in a collection and threads. Another coder might come along and expand this collection more than you planned.
For things like this I usually like to use just the one thread, and a queue - so the events just put the work that needs to be done in a ConcurrentQueue, and the thread starts if not running, and churns through the queued work until it's out of things to do, and dies. The next time more work comes in the event will check if the thread is running and start it.
It's cheaper because if there's a lot going on, you run just the one thread instead of stopping and starting a lot of them, or if there's very little going on, the one thread is almost never running.
Your solution would look more logical if you just put a while() loop in Dowork(), maybe with a little Sleep().
And then there would be no objection against running multiple Bgw's, although you may not see a great speed benefit.
You can do exactly what you describe--just make sure that you pass the reference to the relevant background worker to StartPolling, thusly:
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do it over again
StartPolling((BackgroundWorker)sender);
}
public void StartPolling(BackgroundWorker worker)
{
worker.RunWorkerAsync();
}
Then obviously, you need to manage the collection of BackgroundWorker's accordingly.
Why don't you use the progresschanged event? You could use the userstate object for passing data.
In do work just pool the devices, and in process changed send the data to the UI thread.
Do it in a endless while and use cancel to stop that thread.
Regards.
When you have multiple time consuming tasks to be executed in the same time, I suggest you to use Thread Pool
http://msdn.microsoft.com/en-us/library/ms973903.aspx
Since nobody did it so far, I'll throw in the timer approach. I tried to combine the two (BackgroundWorker and Timer), but that didn't make sense.
I wanted a mechanism to allow multiple instances to request data by thread. Also, I wanted some interval in between.
So after trying around, I figured I could get along with a Timer-approach only:
public void ConnectDataProvider()
{
timer = new Timer(new TimerCallback(tCallback), null, 0, Timeout.Infinite);
}
private void tCallback(object state)
{
timer.Dispose();
// time consuming task
WriteData();
timer = new Timer(new TimerCallback(tCallback), null, 5000, Timeout.Infinite);
}
That was what John Saunders suggested on a similar (but different) problem. It seems to do the job. The WriteData() has a synchronous HttpWebRequest, so it can handle a timeout.
My question now is: How expensive is the new instantiation of the timer object? By how expensive I mean: Are there better ways to achieve that?
Note: The asynchronous approach of the WebRequest won't work, I tried that. I have no clue so far, if that is a manner of the server.

Categories