使用SystemEvents的奇怪行为Console.WriteLine()

时间:2013-06-11 20:04:45

标签: c# console system

Console.WriteLine()不会向屏幕输出任何内容,而在阻止计算机中调用处理程序SystemEvents_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_SessionSwitch()。我特意通过设置断点来检查这一点。并在锁定计算机断点后激活。但是Console.WriteLine()不会向控制台输出任何文本......

2 个答案:

答案 0 :(得分:3)

我可以从问题描述中看出您使用的是.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月左右。

答案 1 :(得分:2)

事件根本没有被调用。在您的支票documentation中,它说:

  

仅在消息泵运行时才会引发此事件。在Windows中   服务,除非使用隐藏的表格或消息泵已经   手动启动,不会引发此事件。