事件被多次提升

时间:2014-01-03 03:19:37

标签: vb.net visual-studio events

我正在尝试创建一个在一定时间后创建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”对象时,似乎不会导致同样的问题。请帮忙。谢谢。

2 个答案:

答案 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实例。正确的问题。感谢您的观看