如何实现SessionSwitch事件单次日志记录,避免重复输出并保持程序运行
问题分析与解决方案
核心问题拆解
- 重复日志原因:原代码在
while(true)循环中反复注册SessionSwitch事件,导致同一个事件处理器被绑定数百上千次,每次事件触发时,所有绑定的处理器都会执行,自然生成重复日志。 - 程序退出原因:移除循环后,
Main方法执行完毕,控制台程序的主线程直接退出,进程终止,无法继续监听系统事件。
修复步骤
- 仅注册一次事件:将事件绑定代码移出循环,放在
Main方法开头,确保事件处理器只绑定一次。 - 阻塞主线程保持程序运行:使用
ManualResetEvent或Console.ReadLine()等方式,让主线程处于等待状态,不直接退出。 - 优化日志写入:添加线程锁避免多线程写入冲突,同时增加时间戳提升日志可读性。
修改后的完整代码
using System; using System.IO; using System.Threading; using Microsoft.Win32; namespace CSharpTutorials { class Program { // 用于线程同步的锁对象,避免日志写入冲突 private static readonly object _logLock = new object(); static void Main() { // 仅注册一次事件处理器,避免重复绑定 SystemEvents.SessionSwitch += SystemEvents_SessionSwitch; // 使用ManualResetEvent阻塞主线程,无需用户输入即可保持程序运行 var resetEvent = new ManualResetEvent(false); resetEvent.WaitOne(); // 若需交互式退出,可替换为以下代码: // Console.WriteLine("程序已启动,监听会话事件...按回车退出"); // Console.ReadLine(); } static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) { string message = e.Reason switch { SessionSwitchReason.SessionLogon => "User logged into the session.", SessionSwitchReason.SessionLogoff => "User logged off the session.", SessionSwitchReason.RemoteConnect => "User remote connected.", SessionSwitchReason.RemoteDisconnect => "User remote disconnected.", SessionSwitchReason.SessionLock => "User locked the computer.", SessionSwitchReason.SessionUnlock => "User unlocked the computer.", _ => string.Empty }; if (!string.IsNullOrEmpty(message)) { RecordLog(message); } } private static void RecordLog(string message) { // 加锁确保多线程下日志写入不会乱序或覆盖 lock (_logLock) { using (StreamWriter writer = File.AppendText("log.txt")) { // 添加时间戳,提升日志可读性 writer.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"); } } } } // 原自定义类可保留,不影响功能 public class MyClass { public int MyProperty { get; set; } } }
关键修改说明
- 事件注册优化:把事件绑定代码从死循环中移出,确保处理器只绑定一次,彻底解决重复日志问题。
- 主线程阻塞方案:用
ManualResetEvent.WaitOne()实现无交互的后台运行,避免原死循环的无效CPU占用;如果需要用户手动退出,可替换为Console.ReadLine()。 - 日志可靠性提升:添加线程锁避免多线程写入冲突,增加时间戳让日志内容更清晰可追溯。
内容的提问来源于stack exchange,提问作者Zac Borders
相关产品推荐
相关产品推荐

