Windows .NET服务 - OnSessionChange事件似乎非常不可靠

Hen*_*erg 7 c# windows service login

我正在用C#编写一个需要跟踪当前活动登录用户的Windows服务.为此,我重写了OnSessionChange事件,以便记录用户何时登录,注销或锁定计算机.这通常在大多数情况下都有效,但有时服务会失去对活动用户的跟踪.在我的日志文件中,我可以看到问题是OnSessionChange方法.每次调用此函数时,我都会输出一些日志信息,显然,OnSessionChange会在某个时候调用错误的顺序.也就是说,如果用户锁定计算机然后再次快速登录,则有时会发生两个OnSessionChange调用,这导致以错误的顺序调用(例如,首先是解锁事件,然后是锁定事件).

有谁知道为什么会这样?这个问题是否有解决方法?

编辑:这是一些示例代码,以使其更清晰(希望):

protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
    try
    {
        var user = _getUserName(changeDescription.SessionId);

        if (changeDescription.Reason == SessionChangeReason.SessionLock ||
            changeDescription.Reason == SessionChangeReason.SessionLogoff ||
            changeDescription.Reason == SessionChangeReason.ConsoleDisconnect)

            LogText(String.Format("{0} locked at {1}\r\n", user, DateTime.Now));

        else if (changeDescription.Reason == SessionChangeReason.SessionUnlock ||
                 changeDescription.Reason == SessionChangeReason.SessionLogon ||
                 changeDescription.Reason == SessionChangeReason.ConsoleConnect)

            LogText(String.Format("{0} unlocked at {1}\r\n", user, DateTime.Now));

        base.OnSessionChange(changeDescription);
    }
    catch (Exception e)
    {
        LogText("Exception: " + e);
    }
}
Run Code Online (Sandbox Code Playgroud)

(函数_getUserName和LogText没有显示,但它们按照他们的名字建议.另外,我从来没有得到异常,所以try-catch-block只是为了验证我实际上没有得到任何.)

现在,有时,在我的日志中我得到这样的事情:

UserA unlocked at 18.01.2015 08:40:29
UserA unlocked at 18.01.2015 08:44:28
UserA locked at 18.01.2015 08:44:28

这是今天早上发生的事情.UserA登录,然后锁定并立即(我认为)再次登录.但是最后两个事件是以错误的顺序被触发的,所以在这个序列之后,我的服务mistekenly认为UserA已经消失了.

通常,我会连续几次获得解锁事件,比如昨天的事件:

UserA unlocked at 17.01.2015 10:55:26
UserA unlocked at 17.01.2015 10:55:26
UserA unlocked at 17.01.2015 10:56:33

或者我可以连续获得几个锁定事件,这可能意味着我在它们之间缺少一个或多个解锁事件:

UserA unlocked at 17.01.2015 09:29:35
UserA locked at 17.01.2015 10:25:28
UserA locked at 17.01.2015 10:30:20

roc*_*cky -1

this.CanHandleSessionChangeEvent 必须设置为 true,默认值为 false。