将一个通用计时器用于许多自定义控件 [英] Use one common timer for many Custom Controls

查看:96
本文介绍了将一个通用计时器用于许多自定义控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好.

我有一个正在闪烁对象的用户控件,并且要在自定义控件中使用计时器.
问题是我在一种表单上有100多个这些控件,它们不同步闪烁,并且当它们都具有运行计时器时,它们会使用很多计算机cpu.

是否有一个仅用一个计时器而不是为每个控件运行计时器的智能解决方案?

谢谢.

Hello.

I got a User control that is flashing a object and to do that I am using a timer in the Custom Control.
The problem is that I am having 100+ of those controls on one form and they dont flash synchronously and uses a lot of the computers cpu when they all have a running timer.

Are there a smart solution for having just one timer instead of having a timer running for each control?

Thanks.

推荐答案

如何为第一次需要的类创建一个计时器?

How about having one timer for the class which is created when it''s first needed?

class MyCleverControl : UserControl {
 private static Timer timer;
 private static Timer Timer {
  get {
   if(timer == null) { timer = new Timer(TimerInterval); timer.Start(); }
   return timer;
  }
 }

 public MyCleverControl(){
  Timer.Tick += (s, e) => { whatever; };
 }
}



如果删除或处理它所使用的表单,则必须编写一些整理代码以停止计时器停顿并永远触发事件(实际上,是让用户控件收集垃圾)



If you remove or dispose of the form that it''s on, you''ll have to write some tidying up code to stop the timer sitting around and firing events forever (and, in fact, to let the user control get garbage collected at all).


当然,有100多个计时器是许多合理的方法.让我们尝试减少计时器的数量.仅考虑一个一个.它将更好:对计时器的处理程序或回调中的所有控件进行所有处理(.NET中存在三种计时器,一种会找到它们的人是一个很酷的人:-).根据要对所有控件执行的操作,可以提供一个包含所有控件的数组,或者提供具有多个控件数组的类实例,每种控件类型一个属性.我不想在此解决方案中进一步详细介绍,因为计时器的数量可以进一步减少.

这是最好的解决方案:使用 0(零)计时器!您不需要任何计时器来进行此类操作,并且使用它们并不容易且容易出错.而是使用单独的线程.在线程中,您需要休眠一段时间(System.Threading.Thread.Sleep),该时间使用零CPU时间,直到线程在时间或Abort到期之前被唤醒为止.当您的主窗体即将关闭时,只需使用System.Threading.Thread.Abort中止该线程即可.如果需要,不要尝试暂停/恢复线程.而是使用类 System.Threading.ManualResetEvent限制线程.

参见:
http://msdn.microsoft.com/en-us/library/system.threading. thread.aspx [^ ],
http://msdn.microsoft.com/en-us/library/system.threading. manualresetevent.aspx [ ^ ].

现在,该线程如何与UI一起使用?

您无法从非UI线程调用与UI相关的任何操作.相反,您需要使用System.Threading.DispatcherInvokeBeginInvoke方法(对于Forms或WPF)或System.Windows.Forms.Control(仅对于Forms).

在我过去的答案中,您将找到有关其工作原理的详细说明和代码示例:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5的问题 [如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].

—SA
Of course, 100+ timers is way to many to be reasonable. Let''s try to reduce the number of timers. Consider just one. It will be much better: do all the processing for all the controls in the handler or callback of this timer (there are three type of timer in .NET, the one who will find them all is a cool guy :-)). Depending on what you want to do with all the controls, you can supply an array of all controls, or a class instance with several arrays of controls, one property per control type. I don''t want to go into further detail in this solution, as the number of timers can be further reduced.

Here is the best solution: use 0 (zero) timers! You don''t need any timers for such thing, and using them is not easy and error-prone. Instead, use a separate thread. In the thread, you need to sleep for some period of time (System.Threading.Thread.Sleep), which uses zero CPU time until a thread is waken up by an expiration of time or Abort. When your main form is about to close, just abort this thread using System.Threading.Thread.Abort. Don''t try to pause/resume thread if you want it. Instead, use the class System.Threading.ManualResetEvent to throttle the thread.

See:
http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx[^],
http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx[^].

Now, how this thread can work with UI?

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


这篇关于将一个通用计时器用于许多自定义控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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