我目前正在研究一个将在一定数量的非活动时间内注销用户的方法。我声明了应用程序.空闲
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
这样做的问题是,每当空闲事件结束时,我仍然会收到通知,指出我再次被锁定和/或应用程序已进入空闲事件。
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
如果我Timer_Tick事件异常上放一个MsgBox(ex.Message)
,我会不断得到
Object reference not set to an instance of an object
我的预期结果是,每当表单进入 Idle 事件时,它将从My.Settings.LockOutTime
获取间隔或时间,这是一个分钟值,并存储为 1 minute
或 60 seconds
的60000
并启动计时器。现在,如果间隔结束,则Timer_Tick logout
用户。
我处理事件的方式有问题吗?
应用程序.空闲事件多次触发。 每次 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
除了汉斯的回答:当用户不再空闲时,您似乎不会停止计时器运行。 也就是说,计时器在我空闲时启动,但如果我回来,当计时器滴答作响时,我仍然会被锁定。
您需要确保在用户再次处于活动状态时停止计时器。