Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# time
I`d like some job be periodically done. This job might be writing files, some processing with resourse handling + sometimes it might be time-consuming. A good candidate for periodic tasks is a Timer clas from System.Timers namespace. However, it raises Elapsed event each time in different thread.

Now imagine I have 500ms Timer period, and the thread from previous Elapsed event did not finished, so the resourses were not released. A thread from "current" Elapsed event tries to get theses resourses, and we`ve got a conflict. I see a solition like the following:
 
class FolderMonitor
{
 Timer monitoringTimer = new Timer(500);
 
 public FolderMonitor(string folderName)
 {
   monitoringTimer.Elapsed += new ElapsedEventHandler(monitoringTimer_Elapsed);
   monitoringTimer.Start();
 }
 
  void monitoringTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            monitoringTimer.Enabled = false;
            try
            {
                //a work with resourses, for example, 
                //take the files from folder and convert them into other format
            }
            finally
            {
                monitoringTimer.Enabled = true;
            }
 
        } 
}
 
Is it OK?
Shall it work s I expect, i.e. no other thread can now even access resourses, while one is working?
Any disadvantages of such solution?
Posted 17-Jun-12 22:15pm
kosmoh8K
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

From your comment on Mehdi's answer I see that the task duration can be much greater than the timer interval and your original solution is OK for that situation.
 
The problem is how to repeat a task, not every 500ms, but 500ms after the task has completed.
 
You have the timer based solution which can be tidied up by setting AutoReset = false so that the timer always stops when it fires.
 
System.Timers.Timer t;
 
void StartTimer()  {
  t = new System.Timers.Timer();
  t.Interval = 500;
  t.AutoReset = false;
  t.Elapsed += TimerProc;
  t.Enabled = true;
}
 
void TimerProc(object sender, System.Timers.ElapsedEventArgs e) {
  Task();
  t.Enabled = true;
}
 
void Task() {
}
 
An alternative approach would be a thread running a loop.
bool repeating;
Thread th;
 
void StartThread() {
  repeating = true;
  th = new Thread(new ThreadStart(ThreadProc));
  th.IsBackground = true;
  th.Start();
}
 
void ThreadProc() {
  while (repeating) {
    Task();
    Thread.Sleep(500);
  }
}
 
void Task() {
}
 
There is little difference between the two techniques and I would probably choose the timer but I'm sure many would prefer the explicit thread approach as it does make it very clear what is happening.
 
i.e. task - delay - task - delay...
 
Alan.
  Permalink  
v2
Comments
kosmoh at 18-Jun-12 7:13am
   
Thanks for your code example: Mehdi mentioned AutoReset property, but I couldn`t understand it`s usage for my case.
Now it`s completely understandable for me, I hope, for other researchers also.
Thanks again :)
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Just put a lock in your timer event handler :
private object _lock = new object();
void monitoringTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock(_lock)
            {
               // your code here
            }
        } 
}
Also you should set AutoReset = True on your timer so it will run continuously.
  Permalink  
Comments
kosmoh at 18-Jun-12 3:34am
   
Thanks for your response.
I`ve found such solution when googled. But what makes me confused is the situation, when the task is too time-consuming.
 
So, first time the Elapsed Thread acquired a lock, and started doing the task, which can take minutes. In 500 milliseconds the other thread appears, and it starts waiting for the lock. Then the other and other...
Isn`t that a problem?

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

  Print Answers RSS
0 OriginalGriff 280
1 Sergey Alexandrovich Kryukov 279
2 CPallini 205
3 Maciej Los 162
4 Afzaal Ahmad Zeeshan 160
0 OriginalGriff 5,635
1 DamithSL 4,496
2 Maciej Los 3,942
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,180


Advertise | Privacy | Mobile
Web01 | 2.8.141216.1 | Last Updated 18 Jun 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100