Scheduling running a method at a certain time. - c#

This is a rather simple issue, but every time I try to find the answer it keeps showing things about Windows Scheduled Tasks, and this is not what this is.
Say my program is basically this:
void StartDoingThings()
{
//At Specific System.DateTime
DoSomething()
//At another specific System.Datetime
DoSomethingElse()
}
What do I put instead of those comments to cause those methods to run at separate datetimes.
I could use Thread.Sleep() or even System.Threading.Timers and calculate intervals based off of (DateTimeOfEvent - DateTime.Now), but is there simply something to say (assuming the program is still running): At 9:30:00 AM on 11/30/2012, perform the method DoAnotherThing() ?

If you want to "schedule" a method to do something at a predetermined time, there are a number of ways to do that. I would not use Thread.Sleep() because that would tie up a thread doing nothing, which is a waste of resources.
A common practice is to use a polling method that wakes up on a regularly timed schedule (let's say once a minute) and review a shared list of tasks to perform. System.Timer can be used for the polling method:
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
The OnTimedEvent method can contain code that maintains a collection of "tasks" to perform. When a task's time comes up, the next run of the Timer will cause it to execute.

Related

What is the best approach to schedule events?

I have an application in which the user is able to create different notifications, like sticky notes and set their starting times. When he presses the start button a timer starts and these reminders should pop up at the time they were set for. I've searched for other answers, like this one, but the problem here is the notifications' times are different.
So what is the best way to schedule the events that activate the notifications?
I can think of two possible ways with their Pros and Cons:
Run a DispatcherTimer, that ticks every second and checks whether the time for a notification has come and pop it up. Pros: single DispatcherTimer instance. Cons: ticking every second and checking all notifications is an overhead.
Create a DispatcherTimer for each notification and let them handle time themselves. Pros: every timer ticks just once to pop the notification. Cons: too many timers is an overhead and may be hard to control.
Am I on the right track? Which of the two approaches is better, resource wise? Is there a third better way I am overlooking?
EDIT: If it makes any difference, the notifications should also auto close after some user-defined time and repeat at regular user-defined intervals.
I've used many methods to schedule events in C# Applications (Threads, Timers, Quartz API...), and I think that the Quertz.NET API -link- is the best tool you'll find (For me at least). It's easy and simple to use.
Example of your job class:
public class HelloJob : IJob
{
public void Execute(IJobExecutionContext context)
{
Console.WriteLine("Greetings from HelloJob!");
}
}
Example from the internet:
// Instantiate the Quartz.NET scheduler
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
// Instantiate the JobDetail object passing in the type of your
// class. Your class needs to implement a IJob interface
var job = new JobDetail("job1", "group1", typeof(HelloJob));
// Instantiate a trigger using the basic cron syntax.
// Example : run at 1AM every Monday - Friday.
var trigger = new CronTrigger(
"trigger1", "group1", "job1", "group1", "0 0 1 ? * MON-FRI");
// Add the job to the scheduler
scheduler.AddJob(job, true);
scheduler.ScheduleJob(trigger);
You'll find a helpful code example in the QuickSart guide here.
Regards.
If the notification system is going to be used inside single process, continue with single dispatcher timer. Make sure the dispatcher timer is set to the near notification. and each time a new notification is created or timer hit ,change the time to next nearest notification.
That way you can avoid processing every time.
eg: First time when somebody creates notification point timer to that time. If someone else create another notification before first hits change the timer to second. If the second time is after the first time, change the timer after dispatching the first notification call back. If its threaded you may need to work hard to get thread safety.
If notification is needed across process use windows task scheduler which already knows how to run timer and call our code on time. You may need to use some sort of IPC (WCF net.pipe, msmq etc...) to achieve notification.

C# Visual Studio - Wait 3 seconds and do something at the end of method and kill the timer?

I am writing a "game" simulating Student's Adventures at The University and what I have done already is few forms, still I need one form to not wait for user input but check if I want an Game Event to run now, if not, then wait few seconds and then skip to another day and repeat the procedure for that day.
The thing is user is able to quit the game at any time and all the information is saved so I need to keep it an one-shot timer of few seconds that doesn't run for another time after it expires.
How do I write an one-shot timer or delay an execution of my c# code for few seconds?
EDIT:
MessageBox.Show("I will wait 3 seconds now");
wait 3 seconds
...
after 3 seconds
MessageBox.Show("3 seconds passed since I poped out last message box!");
If all that you want to do is create a method to "tick" every so often, there are a few options.
The first would be the System.Threading.Timer object, documented on MSDN here: http://msdn.microsoft.com/en-us/library/system.threading.timer%28v=vs.110%29.aspx
An example of this:
public void Tick(object stateInfo /* required to fit TimerCallback signature */)
{
/// add your code here
}
And your Timer instantiation would look like so:
System.Threading.Timer timer = new System.Threading.Timer(Tick, null, 0, 3000);
And thereafter Tick() will be executed every 3 seconds. Feel free to replace the null with an object of your choice so as to keep track of state.
A second, worse choice would be to use a BackgroundWorker. The primary advantage I've found in this is that the ProgressChanged event handler is automatically invoked in the primary UI thread, so you can use it fairly easily for cross-thread code that involves the UI in some sense. Here's the documentation on MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=vs.110%29.aspx
I don't think the BackgroundWorker would be a good choice - it's user-friendly, but it's not really designed to persist infinitely, or activate periodically, so its usage leads to bad workarounds like wrapping all the DoWork code in a while(true) loop and using Thread.Sleep() to pause execution.
A third would be the System.Timers.Timer object, which takes an Interval in milliseconds and an Elapsed event hooked into one of your methods. Each time the interval passes, your method is called. The documentation for that is here: http://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx
Note that all of these work slightly differently, so one may well fit your use case significantly better. We can't really tell you which one is best because we don't really know much about your implementation right now.
http://msdn.microsoft.com/library/system.threading.timer.aspx
static void Main(string[] args)
{
Timer tmr = new Timer(S, null, 0, 5000);
Console.Read();
}
static void S(object obj)
{
Console.WriteLine("1");
}
and u can look here
Execute a method after delay on time only

c# thread dispatching every X minutes

I have a C# program that needs to dispatch a thread every X minutes, but only if the previously dispatched thread (from X minutes) ago is not currently still running.
A plain old Timer alone will not work (because it dispatches an event every X minutes regardless or whether or not the previously dispatched process has finished yet).
The process that's going to get dispatched varies wildly in the time it takes to perform it's task - sometimes it might take a second, sometimes it might take several hours. I don't want to start the process again if it's still processing from the last time it was started.
Can anyone provide some working C# sample code?
Use a while(True) loop in the thread. Record the start time at the top of the loop, perform the task, get the time again, calculate how much time has elaspsed and compare withv the start time. If this is less than X, convert the difference into ms and Sleep() for it.
No timer, no continual thread create, no synchro, no polling, no chance at all that two task instances will ever run concurrently.
you can just check if the thread is alive before you activate another thread.
do this using Thread.IsAlive.
I think a timer could work in this scenario. When the timer elapses it tries to obtain a lock on a synchronisation object. If it succeeds then it proceeds with it's work. If it fails to obtain the lock it knows the last thread has not finished so returns.
If you are using .Net 4.0 or above you could use Monitor.TryEnter(object, bool).
bool acquiredLock = false;
try
{
Monitor.TryEnter(lockObject, ref acquiredLock);
if (acquiredLock)
{
//do your work here
}
}
finally
{
if (acquiredLock)
{
Monitor.Exit(lockObject);
}
}

job incomplete during when by using timer event completes in windowservice c#.net

here i have written a window service, it job is to read files from one folder and sending the same content to database and sending readed files to some other folder
now my service having timer event has sets it was about of 10000 means ten seconds,
now if a process a files between 100 - 1000 ,with in 10 sec it was doing that job processing good output, case if process the files 6000 - 9000 at that particular situation my service is not producing exact out, it was not able to do that job in 10000 (ten seconds), so i need when service in middle of the job it should get interrupted since by timer completed but real scenario it should completed the particular job.
kindly give some suggestions, it would be appreciated
Different approaches that can work:
Have the method called by the timer safe for re-entrance and then not worry about it. This tends to be either very easy to do (the task done is inherently re-entrant) or pretty tricky (if it's not naturally re-entrant you have to consider the effects of multiple threads upon every single thing hit during the task).
Have a lock in the operation, so different threads from different timer events just wait on each other. Note that you must know that there will not be several tasks in a row that take longer than the time interval, as otherwise you will have an ever-growing queue of threads waiting for their chance to run, and the amount of resources consumed just by waiting to do something will grown with it.
Have the timer not set to have a recurring interval, but rather re-set it at the end of each task, so the next task will happen X seconds after the current one finishes.
Have a lock and obtain it only if you don't have to block. If you would have to block then a current task is still running, and we just let this time slot go by to stay out of it's ways.
After all, there'll be another timer event along in 10 seconds:
private static void TimerHandler(object state)
{
if(!Monitor.TryEnter(LockObject))
return;//last timer still running
try
{
//do useful stuff here.
}
finally
{
Monitor.Exit(LockObject);
}
}
Use a static boolean variable named something like IsProcessing.
When you start working on the file you set it to true.
When the timer is fired next check if the file is still in processing.
If it's still processing, do nothing.

What's the most efficient way to call a method every 20 seconds

I would like to call a method passing a parameter every 20 seconds,
e.g.
public void ProcessPerson(IPerson person)
I’ve been reading through the different Timer options and was wondering if anybody could recommend the most efficient way to do this?
In addition, is there a way to keep the parameter strongly typed rather than use object and then have to convert to IPerson?
Thank you for your help.
A System.Threading.Timer is what you need:
Provides a mechanism for executing a method at specified intervals.
Use a TimerCallback delegate to specify the method you want the Timer to execute. The timer delegate is specified when the timer is constructed, and cannot be changed. The method does not execute on the thread that created the timer; it executes on a ThreadPool thread supplied by the system.
There's also the System.Windows.Forms.Timer:
Implements a timer that raises an event at user-defined intervals. This timer is optimized for use in Windows Forms applications and must be used in a window.
This Windows timer is designed for a single-threaded environment where UI threads are used to perform processing.
And don't forget System.Timers.Timer:
The Timer component is a server-based timer, which allows you to specify a recurring interval at which the Elapsed event is raised in your application.
The server-based Timer is designed for use with worker threads in a multithreaded environment. Server timers can move among threads to handle the raised Elapsed event, resulting in more accuracy than Windows timers in raising the event on time.
So investigate each and decide which one works best in your case.
I would go for System.Threading.Timer. Keep in mind that Windows is not a real-time OS system so there will be some variance on the timing no matter what mechanism you choose.
You did not say if this function will be performing any kind of UI updates, but just in case you should also know that the callback function will be executed on a different thread so in some cases like performing UI updates you will need to take the appropriate action to marshal the request back to the UI thread.
To marshal the request back to the UI thread you can do the following
For WinForms you can use Control.Invoke
For WPF you can use Dispatcher.Invoke
Or the Async variant BeginInvoke
You can use this, just make sure whatever you are doing is thread safe.
using System.Threading;
public void DoStuff(IPerson person)
{
new Timer(ProcessPerson, person, 0, 20000);
}
public void ProcessPerson(object threadState)
{
IPerson person = threadState as IPerson;
// do your stuff
}

Categories

Resources