tags:

views:

171

answers:

4

How can I have a WinForms program do some specific thing whenever a certain time-based condition is met?

I was thinking I could do something with two threads, where one thread runs the normal program, and the other thread merely loops through checking if the time-based condition is true yet or not, and when the condition is true it signals an event.

However I am unsure of the best way to do it. Where in the program would I call the two threads? Maybe I am thinking about it all wrong?

How would you do this?

MORE INFO: What it has to do is check the data.dat file and see when the last time it was updated was. If it was a month or more then do the specific thing. Could this still be done with a Timer?

NOTE: I think it might be useful to note the difference between the System.Timers and the System.Windows.Forms.Timer...

+5  A: 

I think you should use a Timer set to an inteligent interval to check if your time-based condition is met.

It depends what your time-based condition is. Is it a special time or an interval after which you want to do something special? If it's the second, you can just use the Timer and do what you have to do when the Timer.Elapsed event is fired.


Edit after your edit: If you want an event to be fired every time the file changes, use a FileSystemWatcher


Edit2: Here's the difference between System.Windows.Forms.Timer and System.Timers:

The Windows Forms Timer component is single-threaded, and is limited to an accuracy of 55 milliseconds. If you require a multithreaded timer with greater accuracy, use the Timer class in the System.Timers namespace.

Peter
I added more relevant info to the question.
Alex Baranosky
Ahhh, I think I had misunderstood you before. Yes, makes complete sense thank you.
Alex Baranosky
Maybe I'm misunderstanding, but with a FileSystemWatcher you have no possibility to check whether the file was last modified more than one month ago. The FileSystemWatch will fire exactly when the file is modified.
M4N
Yes, I just got it to work as I want by using the Timer control, I set it to check every hour. Thanks for the help.
Alex Baranosky
+2  A: 

You could add a System.Windows.Forms.Timer control to your Form (see the Components category in the toolbox).

Then set the timer's interval to some value (e.g. 1000) and add a handler for its Tick event. This handler will then be called once every 1000 milliseconds.

In the handler you can then check if the conditions are met and if yes, start your specific operation.


Update (after you updated the question):

To check if the last modification of a file was more than one month ago, you can use this code:

if (File.GetLastWriteTime("data.dat").AddMonths(1) < DateTime.Now)
{
    // do whatever has to be done
    // if it is a time-consuming task, start a new thread!
}

You can still put this into the Tick event handler of the timer component. But in that case it does probably not make sense to fire the timer every second.

Depending on your application (e.g. if it will be started quite often), another possibility would be to execute the above check during the startup of your application.

M4N
I added more relevant info to the question.
Alex Baranosky
+1  A: 

Regarding your 'more info': How many times must it check the modification-date of that specific file ? Only once (during startup for instance), or should it check the modification-date of that file multiple times during application execution ?

If it has to be done only once, then it is useless to use a timer. If it has to be done multiple times, then yes, you could use a timer.

The eventhandler of the Elapsed event could then check the ModificationDate of the file, and see if action needs to be taken.

Another solution, which is probably more elegant, is using a FileSystemWatcher. This FileSystemWatcher could 'watch' that particalur file. Specify a Filter on the FileSystemWatcher so that, every time the particular File is changed, an event is raised. In the eventhandler of the FileSystemWatcher, you can then take the necessary action:

FileSystemWatcher dataFileWatcher = new FileSystemWatcher();
dataFileWatcher.Path = "path to your file";
dataFileWatcher.Filter = "yourfilename";
dataFileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
dataFileWatcher.NotifyFilter = NotifyFilters.LastWrite;
dataFileWatcher.EnableRaisingEvents = true;

private void OnFileChanged( object sender, FileSystemEventArgs e )
{
   // take action.
}

Note however, that there's a sublte bug / feature in the FileSystemWatcher which causes that the Changed event gets raised multiple times for one change to the File you're watching.

You can resolve this like this

Frederik Gheysels
Thanks for your well-thought0out reply.
Alex Baranosky
+1  A: 

Another alternative, if you know the time between file updates (a month) is to check once at startup time. If the file is out of date you can process it immediately. If not, you can then work out how long you need to wait before checking it again. You can then schedule a task using a wait timer or other methods as described in the answers.

Basically, at startup time you can find out the limit/worst case on how long you have to wait and then you don't need to do any additional checks in the meantime. This assumes of course that the file can't be changed to an OLDER version during the running of the program which seems unlikely, but not impossible!

xan