I'm currently working on a from that will logout the user in a certain amount of inactivity time. I declared Application.Idle
Private Sub Application_Idle(sender As Object, e As EventArgs)
Timer.Interval = My.Settings.LockOutTime
Timer.Start()
End Sub
Then, call it on form load event
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
And on the timer
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
The problem with this is whenever an Idle event is over I'm still getting a notification that I've been lockout again and/or the application has entered an Idle event.
control_acPasswords()
is the logout user control
And here is where I free up memory
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
If I put a MsgBox(ex.Message)
on Timer_Tick event Exception, I keep getting
Object reference not set to an instance of an object
My expected result is whenever the form enters the Idle event, it will get the interval or the time from My.Settings.LockOutTime
which is a minute value and stored as 60000
for 1 minute
or 60 seconds
and start the timer. Now on Timer_Tick then logout
the user if the interval is over.
Is there something wrong how I handle events?
The Application.Idle event fires multiple times. Every time Winforms retrieved all messages from the message queue and emptied it. Problem is, the second and subsequent times it fires, you are starting a timer that was already started. That has no effect, you have to reset it so it starts ticking again for the programmed interval. Easy to do:
Private Sub Application_Idle(sender As Object, e As EventArgs)
Timer.Interval = My.Settings.LockOutTime
Timer.Stop()
Timer.Start()
End Sub
Next problem, possibly the reason for the exception, is that you explicitly have to unsubscribe the event when your form closes. It is not automatic, Application.Idle is a static event. Use the FormClosed event:
Protected Overrides Sub OnFormClosed(ByVal e As System.Windows.Forms.FormClosedEventArgs)
Timer.Stop()
RemoveHandler Application.Idle, AddressOf Application_Idle
MyBase.OnFormClosed(e)
End Sub