2014-01-03 6 views
1

Я пытаюсь создать класс, который будет создавать Relogin через определенное время, но после первого Relogin он будет заселять. Heres my Code:События, возникающие несколько раз

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 

Открытый_Login() срабатывает несколько раз после первого или второго времени. Кажется, что эта проблема не возникает, когда я заменяю объект MainWindow на ящик сообщений. Пожалуйста помоги. Спасибо.

ответ

0

Понял, что это было мое кодирование. Каждый раз, когда MainWindow загружал, он запускал Start(), создавая новый экземпляр Timer. Правильная проблема. Спасибо за просмотр

1

Несмотря на то, что ваша проблема, кажется, решена - использование несинхронизированного счетчика не является надежным способом, чтобы событие запускалось каждый заданный период.

Само событие таймера запускается из отдельного управляемого потока .NET, и впоследствии переменную _timesCalled можно получить из нескольких потоков. Таким образом, возможно, что при повторном настройке _timesCalled=0 из вашей основной темы другой поток из потока threadpool по умолчанию вот-вот перепишет его _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 
+0

Спасибо вам за помощью. Я обязательно изменю это. У меня есть еще один вопрос для вас: как этот таймер отслеживает миллисекунды. То, что я пытаюсь сделать, - установить предопределенное количество времени до окончания сеанса и попросить перелогизировать. Я надеюсь, что Таймер не зависит от Windows Time. – user1489261

+1

Таймер .NET зависит от времени Windows и ограничен разрешением тайм-аутов базовой операционной системы. Это базовое разрешение составляет около 15-20 мс. – mockinterface

+0

Может ли это вызвать отверстие в петле из бесконечного окончания сеанса. Я хотел бы, чтобы моя сессия длилась 48 часов, прежде чем попросить пересмотреть. Я просто не хочу, чтобы пользователь менял время на «продление» таймаута сеанса – user1489261

Смежные вопросы