1

私は現在、一定の非アクティブ時間でユーザーをログアウトする from に取り組んでいます。Application.Idle を宣言しました

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

Timer_TickMsgBox(ex.Message)イベント例外を設定すると、取得し続けます

Object reference not set to an instance of an object

私の予想される結果は、フォームが Idle イベントに入るときはいつでも、My.Settings.LockOutTime分の値である間隔または時間を取得し、またはとして保存し600001 minuteタイマー60 secondsを開始することです。Timer_Tick でlogout、間隔が終了した場合はユーザー。

イベントの処理方法に何か問題がありますか?

4

2 に答える 2

3

Application.Idle イベントが複数回発生します。Winforms がメッセージ キューからすべてのメッセージを取得して空にするたびに。問題は、2回目以降に起動すると、すでに開始されているタイマーを開始していることです。それは効果がありません。プログラムされた間隔で再びティックを開始するようにリセットする必要があります。簡単にできます:

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
于 2012-09-20T10:50:49.047 に答える
2

Hans の回答に加えて、ユーザーがアイドル状態でなくなったときにタイマーの実行を停止しているようには見えません。つまり、アイドル状態になるとタイマーが開始されますが、戻ってきてもタイマーが作動するとロックアウトされます。

ユーザーが再びアクティブになったときにタイマーを停止していることを確認する必要があります。

于 2012-09-20T10:55:46.113 に答える