Приложение. Действует по-разному

В настоящее время я работаю над тем, чтобы выйти из системы через определенное время бездействия. Я объявил приложение

Private Sub Application_Idle(sender As Object, e As EventArgs)
    Timer.Interval = My.Settings.LockOutTime
    Timer.Start()
End Sub

Затем вызовите его на событие загрузки формы

Private Sub ctlManagePw_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    AddHandler System.Windows.Forms.Application.Idle, AddressOf Application_Idle
End Sub

И по таймеру

Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
    Try
        If My.Settings.TrayIcon = 1 Then
            Me.ParentForm.Controls.Remove(Me)
            control_acPasswords()
            _Main.NotifyIcon.Visible = True
            _Main.NotifyIcon.ShowBalloonTip(1, "WinVault", "You've been locked out due to innactivity", ToolTipIcon.Info)
        End If
        'Stop
        Timer.Stop()
        Timer.Enabled = False
        'Flush memory
        FlushMemory()
    Catch ex As Exception
        'Error is trapped. LOL
        Dim err = ex.Message
    End Try
End Sub

Проблема в том, что всякий раз, когда событие Idle заканчивается, я все еще получаю уведомление о том, что я снова заблокирован и / или приложение вошло в событие Idle.

control_acPasswords() это выход пользователя из системы управления

И вот где я освобождаю память

Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal process As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Integer
Public Sub FlushMemory()
    Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
        If (Environment.OSVersion.Platform = PlatformID.Win32NT) Then
            SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1)
            Dim myProcesses As Process() = Process.GetProcessesByName(Application.ProductName)
            Dim myProcess As Process
            For Each myProcess In myProcesses
                SetProcessWorkingSetSize(myProcess.Handle, -1, -1)
            Next myProcess
        End If
    Catch ex As Exception
        Dim err = ex.Message
    End Try
End Sub

Если я поставлю MsgBox(ex.Message)на исключение события Timer_Tick, я продолжаю получать

Object reference not set to an instance of an object

Мой ожидаемый результат - всякий раз, когда форма входит в событие Idle, она получает интервал или время от My.Settings.LockOutTime который является минутным значением и хранится как 60000 за 1 minute или же 60 seconds и запустить таймер. Теперь на Timer_Tick тогда logout пользователь, если интервал закончен.

Что-то не так, как я справляюсь с событиями?

2 ответа

Решение

Событие Application.Idle запускается несколько раз. Каждый раз Winforms извлекали все сообщения из очереди сообщений и очищали их. Проблема в том, что во второй и последующие разы он запускается, вы запускаете таймер, который уже был запущен. Это не имеет никакого эффекта, вы должны сбросить его, чтобы он снова начал работать в течение запрограммированного интервала. Легко сделать:

Private Sub Application_Idle(sender As Object, e As EventArgs)
    Timer.Interval = My.Settings.LockOutTime
    Timer.Stop()
    Timer.Start()
End Sub

Следующая проблема, возможно, причина исключения, заключается в том, что вам необходимо отменить подписку на событие, когда ваша форма закрывается. Это не автоматически, Application.Idle является статическим событием. Используйте событие FormClosed:

Protected Overrides Sub OnFormClosed(ByVal e As System.Windows.Forms.FormClosedEventArgs)
    Timer.Stop()
    RemoveHandler Application.Idle, AddressOf Application_Idle
    MyBase.OnFormClosed(e)
End Sub

В дополнение к ответу Ганса: вы не останавливаете таймер, когда пользователь больше не находится в режиме ожидания. То есть, таймер запускается, когда я бездействую, но если я вернусь, я все равно буду заблокирован, когда таймер тикает.

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

Другие вопросы по тегам