我的表单上有大约20个计时器,所有计时器都有不同的间隔。 例如,一个间隔为25,一个间隔为100,但有些间隔也有“不规则”间隔,如43.
我想只有一个计时器并处理其Tick事件中的所有内容。
例如:
Private Sub _TmrAll_Tick(sender As Object, e As EventArgs) Handles _TmrAll.Tick
_iTimer += 25
If _iTimer Mod 25 = 0 Then
pHandleClickDelayRepeat()
End If
If _iTimer Mod 100 = 0 Then
pHandleSkype()
End If
If _iTimer Mod 43 = 0 Then 'this of course would not work with my current approach
pHandleMouse()
End If
它认为我目前的方法并不是很好,因为我不能轻易处理这些不规则的间隔。
有没有人更好地了解如何做到这一点?
谢谢。
答案 0 :(得分:0)
问题是,你总是在检查之前添加值 应该完成。
_iTimer += 25
必须写在If条件下。
答案 1 :(得分:0)
假设_iTimer是一个全局变量,用于计算循环,你应该增加1而不是25.否则你将永远不会达到你的“不规则”间隔。您应该将计时器间隔更改为1000(基于1秒)并将1递增1(_iTimer + = 1)。
答案 2 :(得分:0)
您只需要一个计时器,并将间隔设置为所有间隔的最大除数(没有余数)。
在你的情况下,43只能除以43或1.你不能使用43,因为这不是25的除数,所以你唯一的选择是1.这意味着当它什么也不做的时候它会被激活很多次但这并不重要。
因此,只需跟踪区间变量(您可以使用静态变量来保持范围尽可能小)。像这样:
Private Sub _TmrAll_Tick(sender As Object, e As EventArgs) Handles _TmrAll.Tick
Static intervalCount As Integer = 0
intervalCount += 1
If intervalCount Mod 25 = 0 Then
pHandleClickDelayRepeat()
End If
If intervalCount Mod 100 = 0 Then
pHandleSkype()
End If
If intervalCount Mod 43 = 0 Then
pHandleMouse()
End If
End Sub
答案 3 :(得分:0)
我建议您使用Microsoft的Reactive Framework(称为Rx)。只是NuGet“Rx-WinForms”。
这是我的代码:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim cs = New ControlScheduler(Me)
Dim subscription1 =
cs.SchedulePeriodic(
TimeSpan.FromMilliseconds(25.0),
Sub() pHandleClickDelayRepeat())
Dim subscription2 =
cs.SchedulePeriodic(
TimeSpan.FromMilliseconds(100.0),
Sub() pHandleSkype())
Dim subscription3 =
cs.SchedulePeriodic(
TimeSpan.FromMilliseconds(43.0),
Sub() pHandleMouse())
End Sub
Rx为我们提供了一堆可以直接使用的调度程序。我选择了ControlScheduler
来确保将预定事件推送到UI线程。
ControlScheduler
实际上是您应用中的单个计时器。
您可以直接使用调度程序,也可以单独根据间隔创建自己的可观察对象,并在ControlScheduler
上观察它们。
Dim cs = New ControlScheduler(Me)
Dim subscription1 =
Observable _
.Interval(TimeSpan.FromMilliseconds(25.0)) _
.ObserveOn(cs) _
.Subscribe(Sub() pHandleClickDelayRepeat())
Dim subscription2 =
Observable _
.Interval(TimeSpan.FromMilliseconds(100.0)) _
.ObserveOn(cs) _
.Subscribe(Sub() pHandleSkype())
Dim subscription3 =
Observable _
.Interval(TimeSpan.FromMilliseconds(43.0)) _
.ObserveOn(cs) _
.Subscribe(Sub() pHandleMouse())
第二种方法可以让你做各种很酷的查询。
Dim query =
From n In Observable.Interval(TimeSpan.FromMilliseconds(193.0))
Where n * 2 Mod 3 = 1
Select "Foo" & n * 5
Dim subscription4 = query.ObserveOn(cs).Subscribe(Sub(x) Me.Label1.Text = x)
每当您想要停止其中一个预定的操作或观察者订阅时,您只需在其上调用.Dipose()
,如下所示:
subscription1.Dispose()
subscription2.Dispose()
subscription3.Dispose()
subscription4.Dispose()
答案 4 :(得分:0)
似乎您只需要确定哪个计时器触发事件以执行该计时器的特定任务。如果是这种情况,那么您应该只设置计时器的Tag属性(在设计时或以编程方式创建Timer),并在事件触发时执行触发事件处理程序的计时器所需的代码。 /> 无需使用定时器间隔来识别定时器。
Private Sub _TmrAll_Tick(sender As Object, e As EventArgs) Handles _TmrAll.Tick
Dim tm = CType(sender, System.Windows.Forms.Timer)
Select Case tm.Tag.ToString
Case "Delay"
pHandleClickDelayRepeat()
Case "Skype"
pHandleSkype()
Case "Mouse"
pHandleMouse()
Case Else
Debug.WriteLine("Tag not expected")
End Select
End Sub