System.Timers.Timer是“单线程的".用法 [英] System.Timers.Timer "single-threaded" usage

查看:513
本文介绍了System.Timers.Timer是“单线程的".用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望定期做一些工作.这项工作可能是写文件,使用资源处理进行某些处理,有时可能会很耗时.定期任务的一个很好的选择是来自System.Timers名称空间的Timer类别.但是,它每次在不同的线程中引发Elapsed事件.

现在,假设我有500ms的Timer周期,并且上一个Elapsed事件的线程没有完成,因此资源没有释放.来自当前" Elapsed事件的线程试图获取这些资源,并且我们发生了冲突.我看到如下所示的孤独:

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?

推荐答案

从您对Mehdi的回答的评论中,我看到任务持续时间可能比计时器间隔和原始解决方案长得多.在那种情况下还可以.

问题是如何重复执行任务,而不是每500ms重复一次,而是在任务完成后500ms重复一次.

您有基于计时器的解决方案,可以通过设置AutoReset = false来进行整理,以使计时器在触发时始终停止.

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.


只需在您的计时器事件处理程序中放一个锁:
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
            }
        } 
}


另外,您还应该在计时器上设置AutoReset = True,这样它将连续运行.


Also you should set AutoReset = True on your timer so it will run continuously.


这篇关于System.Timers.Timer是“单线程的".用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆