如何以确切的间隔重复线程? C# [英] How do I repeat thread with exact interval? C#

查看:74
本文介绍了如何以确切的间隔重复线程? C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 private volatile bool _pause = false;
 private ManualResetEvent _pauseEvent = new ManualResetEvent(true);
 private Thread m_thread;
 private bool _istoday = true;
 private bool _isTimer_stop = false;
 private bool _thread_start = true;

private void btn_start_Click(object sender, EventArgs e)
 {

     int timer_interval = (int)numeric_app_freequency.Value;

         timer1_Tick(sender, e);
         timer1.Interval = 60 * 1000 * timer_interval;
         timer1.Enabled = true;
         timer1.Start(); //

 }

 private void timer1_Tick(object sender, EventArgs e)
 {
     if (_thread_start == true)
       {
         _thread_start = false;
         _istoday = true;
         m_thread = new Thread(new ThreadStart(begin_thread));
         m_thread.Name = "thred_1";
         m_thread.IsBackground = true;
         m_thread.Start();

        }

 }

 private void begin_thread()
 {

     int pageNum = 1;

     while (_pauseEvent.WaitOne())
     {
         if (_istoday == true)
         {

             parse_trs(pageNum);
             pageNum++;

         }
         else
         {
             Textbox1.Text = "Work is done"; ;
             break;
         }

     }
     _autoEvent.Set();
 }

 private void parse_trs(int pageNum)
 {
     string str_pageNum = pageNum.ToString();

     string list_url = "http://somedomain.com/bbs/board.php?bo_table=funny&page=" + str_pageNum;

     WebClient client = new WebClient();
     string sourceUrl = client.DownloadString(list_url);

     HtmlAgilityPack.HtmlDocument mydoc = new HtmlAgilityPack.HtmlDocument();

     mydoc.LoadHtml(sourceUrl);


     HtmlNodeCollection tr_col = mydoc.DocumentNode.SelectNodes("/ html / body//div[@id="bo_list"]//table/tbody/tr");

     foreach (HtmlNode node in tr_col)
     {

         _pauseEvent.WaitOne();


         if (post_date == today_date)
         {

             Do work.......................................

         }
         else
         {
             _istoday = false;
             break;
         }

     }
 }





什么我试过了:



我用过while循环代替计时器而cpu重载所以应用程序freez



What I have tried:

I have used while loop instead of timer but cpu overloads so the application freez

推荐答案

这可能是最糟糕的设计,可以获得一些线程的近周期行为。这有很多原因,无需全部讨论。创建新线程实例并启动它的成本是其中一个因素,但到目前为止,并非最坏的因素。最糟糕的是很容易搞乱一切。



更好的直接解决方案是创建只有一个额外的线程,并在几乎所有的线程中保持它的执行应用寿命。你只需让它在一个无限循环中执行(事实上,只有当应用程序即将关闭时才会中断)并通过使用事件等待句柄对象来限制它的活动。



重要的是要理解在调用 WaitHandle.WaitOne 时,线程要么通过,要么被置于特殊的等待状态;它被关闭,从未被调度回执行,直到它被唤醒,这发生在 Thread.Abort Thread.Interrupt ,timeout和其他事件,特别是从另一个线程发出等待句柄对象的信号。这样,线程在等待状态下花费零CPU时间,没有旋转等待,没有定期检查状态,没有。



请参阅: EventWaitHandle类(System.Threading) [ ^ ]。



请查看我过去的答案:

使代码线程安全 [ ^ ],

暂停正在运行的线程 [ ^ ],

线程中的ManualResetEvent和AutoResetEvent [ ^ ],

只运行一个作业/线程/流程在永远不会被终止的webservice(asp.net) [ ^ ]。



特别注意使用a的替代相关技术阻止收集;它与您的直接问题无关,但很重要。



现在,让我们回到计时器的周期性重复。我不确定你是否需要这种方式。另一种选择是在一个线程中自己重复一段代码,从当前实时开始,比如 System.DateTime.Now ,计算下一个执行时间和以适当的持续时间调用 Thread.Sleep 。但是如果你真的需要一个计时器(再次,我不知道为什么),它唯一的功能就是通过调用 EventWaitHandle.Set()来发出事件等待句柄,它会唤醒等待此事件句柄实例的线程。请注意,此调用是线程安全的,与几乎所有其他方法的调用不同。还要注意,计时器事件发生在你不知道的某个线程中(除了非常糟糕的 System.Windows.Forms.Timer ,它调用UI线程中的tick处理程序,但是这种救济是它唯一的好处;在大多数情况下,它永远不应该被使用,因为时机非常糟糕。)



这两种技术解决了你最大的问题可能面临。如果您之前的计时器滴答导致的处理尚未完成,那么如果您开始处理会发生什么?可能很难想象所有可能的混乱。我建议的解决方案完全没有这个问题。



-SA
This is probably the worst possibly design for getting some periodic on near-periodic behavior of a thread. There are many reasons for that, no need to discuss them all. The cost of creation of a new thread instance and starting it is one of the factors, but, by far, not the worst. The worst thing is the easy possibility to mess up everything.

Much better straightforward solution would be creation of only one additional thread and keeping it executing during pretty much all of the application lifetime. You simply make it executing in an "infinite" loop (in fact, broken only when the application is about to close) and throttle its activity by using an event wait handle object.

It's important to understand that on the call WaitHandle.WaitOne the thread either passes or is put to a special wait state; it is switched off and never scheduled back to execution until it is waken up, which happens on Thread.Abort, Thread.Interrupt, timeout, and other events, in particular, signalling the wait handle object from another thread. This way, the thread spends zero CPU time in wait state, there is no spin wait, not periodic checks of the state, nothing.

Please see: EventWaitHandle Class (System.Threading)[^].

Please see my past answers:
Making Code Thread Safe[^],
pause running thread[^],
ManualResetEvent and AutoResetEvent in Thread[^],
Running exactly one job/thread/process in webservice that will never get terminated (asp.net)[^].

Pay special attention for the alternative related technique of using a blocking collection; it is unrelated to your immediate question but important to understand.

Now, let's come back to "periodic" repetition by timer. I'm not sure you need it this way. One alternative would be just repeating the piece of code in a thread on its own, taking current real time from, say, System.DateTime.Now, calculation of next execution time and calling Thread.Sleep with appropriate duration. But if you really need a timer (again, I don't know why), its only function would be signaling event wait handle by calling EventWaitHandle.Set(), which wakes up the thread waiting on this event handle instance. Note that this call is thread-safe, unlike almost any other call of some methods. Also note that the timer event happens in some thread you don't know (except really bad System.Windows.Forms.Timer which invokes the tick handler in the UI thread, but this "relief" it its only benefit; in most cases, it should never be used, as the timing is devastatingly bad).

Both techniques solves the biggest problem you may face. What could happen if you start some processing if the processing caused by your previous timer tick is not yet complete? It can be hard to imagine all the possible mess. The solutions I suggest are completely free from this problem.

—SA


这篇关于如何以确切的间隔重复线程? C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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