C# 带有SystemEvents的奇怪行为控制台.WriteLine()

C# 带有SystemEvents的奇怪行为控制台.WriteLine(),c#,console,system,C#,Console,System,Console.WriteLine()不向屏幕输出任何内容,而处理程序SystemEvents\u SessionSwitch()在阻塞计算机中被调用。但是,如果Main()方法中至少调用一次方法Console.WriteLine(),那么处理程序中的方法将工作。这种奇怪行为/错误的原因是什么 我正在使用Windows 8 64位.NET Framework 4.0 using System; using Microsoft.Win32; namespace TestWindowsEvents

Console.WriteLine()不向屏幕输出任何内容,而处理程序SystemEvents\u SessionSwitch()在阻塞计算机中被调用。但是,如果Main()方法中至少调用一次方法Console.WriteLine(),那么处理程序中的方法将工作。这种奇怪行为/错误的原因是什么

我正在使用Windows 8 64位.NET Framework 4.0

using System;
using Microsoft.Win32;

namespace TestWindowsEvents
{
    class Program
    {
         static void Main(string[] args)
         {
             SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
             //Console.WriteLine("Test"); //if uncomment this line, then Console.WriteLine() in SystemEvents_SessionSwitch() will work
             Console.ReadKey();
         }

         static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
         {
             Console.WriteLine("SessionSwitch"); //this does not working 
             System.Diagnostics.Debug.WriteLine("SessionSwitchDebug"); //and this does not working too..
         }
    }
}
更新:
调用处理程序本身SystemEvents\u SessionSwitch()。我通过设置断点专门检查了这一点。并在锁定计算机后激活断点。但是Console.WriteLine()不向控制台输出任何文本…

事件只是不被调用。你的支票上写着:

仅当消息泵正在运行时才会引发此事件。在窗户里 服务,除非使用了隐藏表单或消息泵已关闭 手动启动,将不会引发此事件


事件根本不被调用。你的支票上写着:

仅当消息泵正在运行时才会引发此事件。在窗户里 服务,除非使用了隐藏表单或消息泵已关闭 手动启动,将不会引发此事件


从对问题的描述可以看出,您正在使用.NET 4.5。您的Console.ReadKey()方法采用锁,这是4.5中的新行为,它防止其他线程写入控制台并扰乱显示

该锁阻止事件处理程序写入控制台。它在另一个线程上运行,这是必要的,因为您使用的是一个控制台模式程序,它不会产生消息循环。SystemEvents类将创建自己的类,以确保触发事件。在这一点上,投赞成票的答案是错误的

它试图写入的内容最终会到达控制台,但这当然发生在控制台窗口关闭前一毫秒,因此您永远看不到它

这种新的4.5行为确实意味着测试某些东西的快速程序的末日。你需要一个更好的方法来决定你的程序是否完成,“点击任意键继续”的方法不再有效。一个不需要锁的相当蹩脚的替代方案可能是:

        while (!Console.KeyAvailable) System.Threading.Thread.Sleep(100);


更新:通过Windows UPDATE提供的.NET 4.5更新修复了此问题。不太清楚我是什么时候得到更新的,大约在2013年8月。

我可以从对问题的描述中看出您正在使用.NET 4.5。您的Console.ReadKey()方法采用锁,这是4.5中的新行为,它防止其他线程写入控制台并扰乱显示

该锁阻止事件处理程序写入控制台。它在另一个线程上运行,这是必要的,因为您使用的是一个控制台模式程序,它不会产生消息循环。SystemEvents类将创建自己的类,以确保触发事件。在这一点上,投赞成票的答案是错误的

它试图写入的内容最终会到达控制台,但这当然发生在控制台窗口关闭前一毫秒,因此您永远看不到它

这种新的4.5行为确实意味着测试某些东西的快速程序的末日。你需要一个更好的方法来决定你的程序是否完成,“点击任意键继续”的方法不再有效。一个不需要锁的相当蹩脚的替代方案可能是:

        while (!Console.KeyAvailable) System.Threading.Thread.Sleep(100);


更新:通过Windows UPDATE提供的.NET 4.5更新修复了此问题。不太清楚我是什么时候得到更新的,大约在2013年8月左右。

事实上,事情是这样的。我通过在处理程序中放置一个断点专门检查了这一点。并在锁定计算机后激活断点。但是Console.WriteLine()不向Console输出任何文本…此MSDN说明不太准确。如果程序的主线程不适合完成任务,SystemEvents将启动自己的线程并泵送消息循环。线程的单元状态很重要,它是C#控制台模式应用程序中的MTA。这也是为什么OP看到事件实际发生的原因。他有一个不同的问题。事实上,这就是所谓的问题。我通过在处理程序中放置一个断点专门检查了这一点。并在锁定计算机后激活断点。但是Console.WriteLine()不向Console输出任何文本…此MSDN说明不太准确。如果程序的主线程不适合完成任务,SystemEvents将启动自己的线程并泵送消息循环。线程的单元状态很重要,它是C#控制台模式应用程序中的MTA。这也是为什么OP看到事件实际发生的原因。他有一个不同的问题。非常感谢!它真的有效!但奇怪的是,我实际上使用的是第四个版本,而不是4.5。我刚刚通过查看项目属性再次检查了它。如果同时安装了4.5,则不能使用“第四版”。4.5覆盖了4.0。在项目中以4.0为目标只会阻止您意外使用4.5中不可用的类。我不知道。非常感谢!它真的有效!但奇怪的是,我实际上使用的是第四个版本,而不是4.5。我刚刚通过查看项目属性再次检查了它。如果同时安装了4.5,则不能使用“第四版”。4.5覆盖了4.0。在项目中以4.0为目标只会阻止您意外使用4.5中不可用的类。我不知道。