我正在尝试创建一个在一定时间后创建Relogin的类,但是在第一个Relogin之后它会继续填充。继承我的代码:
Private Shared timer As Timer
Public Shared Event DoSomething As Action(Of Integer)
Private Shared _timesCalled As Integer = 0
Public Shared Sub Start()
AddHandler DoSomething, AddressOf EventHandler
timer = New System.Threading.Timer(AddressOf timer_Task, Nothing, 0, 1000)
End Sub
Public Shared Sub [Stop]()
timer.Dispose()
End Sub
Private Shared Sub timer_Task(State As Object)
_timesCalled += 1
If _timesCalled = 15 Then 'Should Raise event every 15s
RaiseEvent DoSomething(_timesCalled)
End If
End Sub
Private Shared Sub EventHandler(ByVal EventNumber As Integer)
My.Application.Dispatcher.Invoke(New Action(AddressOf OpenLogin))
End Sub
Private Shared Sub OpenLogin() 'This event fires multiple times after the first Event
Dim x As New MainWindow
x.ShowDialog() 'Dialog stops code from continuing.
x = Nothing
_timesCalled = 0
End Sub
Open_Login()在第一次或第二次之后多次触发。当我用消息框替换“MainWindow”对象时,似乎不会导致同样的问题。请帮忙。谢谢。
答案 0 :(得分:1)
尽管您的问题似乎已得到解决 - 使用非同步计数器并不是每个预定时间内触发事件的可靠方法。
计时器事件本身从一个单独的.NET托管线程触发,随后,可以从多个线程访问_timesCalled
变量。因此,当您从主线程重新设置_timesCalled=0
时,默认线程池中的另一个线程可能会使用_timesCalled=14
覆盖它。
在您的具体示例中,在完成处理计时器事件后重新计划计时器事件更简单,更直接。这样,您还可以计算处理事件所需的时间以及计时器的不准确和滞后。
Public Shared Sub Start()
...
' assuming this runs only once
timer = New System.Threading.Timer(AddressOf timer_Task, Nothing, 15000, Timeout.Infinite)
End Sub
Private Shared Sub timer_Task(State As Object)
RaiseEvent DoSomething(_timesCalled)
End Sub
Private Shared Sub OpenLogin()
Dim x As New MainWindow
x.ShowDialog()
x = Nothing
' Reschedule the timer again here, adjust the 15000 if necessary, maybe prefer timer.ChangeTime(...) instead
End Sub
答案 1 :(得分:0)
弄清楚这是我的编码。每次MainWindow加载它都会运行Start()创建一个新的Timer实例。正确的问题。感谢您的观看