我在Windows和WPF应用程序中搜索了几个用于计时器控制的链接,但我会对我的情况提出一些建议......
当我使用WPF时,初始选项似乎是System.Windows.Threading.DispatcherTimer
或System.Diagnostics.Stopwatch
我需要实现的是每个WPF DocumentPanel
以定义的时间间隔(通常为100毫秒) - 任何时间最大值以及每个DocumentPanel
的唯一间隔请求来自外部API的更新。例如DP1可能是100ms,DP2可能是20,000ms等。
通常我的应用程序将从1个DocumentPanel开始,但是用户可以无限制地扩展面板,这是用户对CPU能力和应用程序速度的判断。
标准包括:
多个DocumentPanels - 通常最少1到20个,但欢迎任何关于可扩展性的建议。
可变事件间隔(Iv)(最小事件间隔100ms - 最大<1天)
准确度 - 1ms(在任何情况下都不能有低于(Iv)ms的间隔,过度没有那么多关注,但需要在几毫秒内)编辑:1ms不是严格要求,而是平均(iv)必须在短时间内保持。
每个DocumentPanel
必须显示实时日期/时间,但会根据设置的时间间隔生成事件
我真的在设计考虑方面提供帮助,而不是实际的代码,因为WPF让我感到困惑。
目前,我正准备使用System.Diagnostics.Stopwatch
的单个实例,并允许每个小组对秒表事件采取行动,无论是否已达到间隔时间。
有人可以提供建议吗?
谢谢 0
答案 0 :(得分:1)
最好只使用一个System.Windows.Threading.DispatcherTimer
和100ms作为刻度,然后使用标签来确定自己的间隔,例如你可以使用
struct IntervalComparer
{
int myinterval; //the individual update interval (300ms for example)
int currentinterval;
public IntervalComparer(int myinterval)
{
this.myinterval=myinterval;
this.currentinterval=0;
}
public void TickMe()
{
currentinterval++;
}
public void ResetkMe()
{
currentinterval = 0;
}
public bool CanIUpdate()
{
return myinterval == currentinterval;
}
}
关于创作
.... Form_Loaded....
{
.....
mypanel=new Panel();
mypanel.Tag= new IntervalComparer(2); // 2 * 100ms
.....
}
.... Timer_Tick....
{
....
(mypanel.Tag as IntervalComparer).TickMe();
if((mypanel.Tag as IntervalComparer).CanIUpdate())
{
UpdateMyPanel();//your update method
(mypanel.Tag as IntervalComparer).ResetMe();
}
....
}
答案 1 :(得分:1)
通常在这种情况下,我会有一个计时器,然后检查每个DocumentPanel的经过时间。我猜测100%的准确度并不重要,如果他们选择999ms,那么他们就不会注意到你的主计时器是否每50ms发射一次,所以只能给它们增加50ms。 Windows无论如何都没有提供那种准确性,我在尝试触发一次闪存时学到了这一点。
答案 2 :(得分:1)
我使用以下方法在Silverlight应用程序中实现类似的功能:
单个计时器,以小间隔打勾(您可以自行决定,但需要低于支持的最低更新间隔),然后让每个DocumentPanel订阅此计时器的计时事件。
当触发tick事件时,每个DocumentPanel将根据它的更新频率(E.G.(last update - now)&gt; interval)确定是否需要更新。
这里有一些计时器类的比较:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
没有提到DispatcherTimer,但DispatcherTimer和System.Timers.Timer之间的重要区别是:
如果在WPF应用程序中使用System.Timers.Timer,则值得 注意到System.Timers.Timer在不同的线程上运行 用户界面(UI)线程。为了访问用户的对象 接口(UI)线程,有必要将操作发布到 使用Invoke或用户界面(UI)线程的调度程序 BeginInvoke的。使用DispatcherTimer的原因与 System.Timers.Timer是DispatcherTimer在同一个上运行的 线程作为Dispatcher和DispatcherPriority可以在上面设置 DispatcherTimer。
(来自http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx)。
在不知道您当前如何处理UI更新以及您如何构建程序的情况下,很难说您应该使用哪个计时器。
我对使用StopWatch并不是很熟悉,但我的意见是(在阅读http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx之后)使用单个StopWatch并不是特别适合这个问题的东西
答案 3 :(得分:0)
如果您需要Tag
属性&amp;,则可以从DocumentPanel继承使用更多封装
class UpdatableDocumentPanel : DocumentPanel
{
public int myinterval { get; set; }//the individual update interval (300ms for example)
int currentinterval;
public void Update()
{
currentinterval++;
if (myinterval == currentinterval)
{
currentinterval = 0;
UpdateMyPanelMethod();
}
}
}
和
.... Form_Loaded....
{
.....
mypanel.myinterval = 2; // 2 * 100ms
.....
}
.... Timer_Tick....
{
....
mypanel.Update(); // simply
....
}