Click here to Skip to main content
15,904,153 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I wrote a watcher program a while back that needs some updating. I figured I'd correct an issue while I do that. Right now it's pretty simple. It has a timer (just a windows forms timer) that ticks every few seconds or minutes depending on a user setting in an XML file. At each tick, it looks for text files to process, grabs them, parses them and then puts the data into a database. It's been running fine for a few years now.

The problem is that if there are a lot of files to process at once and the user wants to stop the system, it's very tricky. You have to keep clicking the stop button until you get just the right spot in code where it's between tick events. it's also a pain just moving or minimizing the form. If it's in the middle of a timer tick event then you have to wait. Also, the text box on the form that updates the user with the status of each file only gets updated on each tick so if it processes 20 files in a tick then you have to wait for all of them to see what happened. Not the ideal setup obviously even though it gets the job done.

It only processes a few at a time for each tick even if there are dozens to process. Anyway, I added background worker code to a new app I just built and would like to do that with this one. But I'm getting the impression that working that into a timer driven app is different. I read that using system.threading.timer is wrong for windows forms (this app runs as a form, not as a service). So I'm not sure how to approach this.

The way its' set up right now, is that on the timer tick event, it calls a routine that checks for files to be processed. If there are files, then that routine saves the file names in an array and then loops through the array. In the loop, another routine is called to process each file one at a time. I don't know where to put the background worker code if that's the right way to do it.

Any help would be appreciated.

Thanks.
Posted

Do yourself a big favor and do not use any kind of timers for this purpose — stay away of trouble!

Instead, always create and use a processing thread. Even in the case you need to do the polling as you do (which is bad by itself but you probably cannot change the architecture, but — see below), you can use Thread.Sleep in this thread in a loop to implement periodic data processing. This schema is stable, the one based on a timer is not. (Did you try to design correct handling of the situation, when a new timer event is fired when the handler triggered by the previous event is not yet finished? With a thread you won't have such problems).

To see, what's involved, look at my collection of my past answers on similar topics:
How to get a keydown event to operate on a different thread in vb.net[^].

Maybe you still can avoid polling of the file structure. Use the class System.IO.FileSystemWatcher; it will notify to any changes in file structure you subscribe to.

—SA
 
Share this answer
 
Comments
Tarakeshwar Reddy 24-Apr-11 14:59pm    
I would agree with SA, if possible a FileSytemWatcher would do you good. My 5
Sergey Alexandrovich Kryukov 24-Apr-11 21:05pm    
Thank you, Tarakeshwar.
--SA
Take a look at this article[^]. The article is in c# but should give you an idea.

You can put your file processing in the background worker and before you process each file (or what ever logic you use) you could check if CancellationPending and stop the thread and also report the necessary progress to the user.
 
Share this answer
 
Comments
avianrand 23-Apr-11 18:24pm    
Thanks. I'll check it out. That makes sense. At a glance it looks like by using CancellationPending, there's no need for a timer?
Tarakeshwar Reddy 23-Apr-11 18:35pm    
It depends, according to your question, looks like you are using the timer to fire the process event. You could use both in parallel.
avianrand 23-Apr-11 18:35pm    
You're right. I got a little ahead of myself when I responded to your answer. LOL.
Sergey Alexandrovich Kryukov 24-Apr-11 13:45pm    
This is correct suggestion. But timer is evil. Also, you can get events from FileSystemWatcher. My 4.
Please see my answer.
--SA
Tarakeshwar Reddy 24-Apr-11 14:59pm    
I was going to suggest a file watcher, but the op mentioned that user would select the interval in which the files would get processed. Since I did not know the requirement, I stopped short with just pointing to the BackgroundWorker article.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900