Console.WriteLine()与SystemEvents的奇怪行为
本文关键字:SystemEvents WriteLine Console | 更新日期: 2023-09-27 18:17:52
Console.WriteLine()不向屏幕输出任何内容,而在阻塞计算机中调用处理程序SystemEvents_SessionSwitch()。但是,如果在Main()方法中至少调用一次Console.WriteLine()方法,则处理程序中的方法将正常工作。这个奇怪的行为/bug的原因是什么?
我使用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()不输出任何文本到console…
从问题的描述中我可以看出你正在使用。net 4.5。你的console . readkey()方法需要一个锁,这是4.5中的新行为,它可以防止其他线程写入控制台并弄乱显示。
该锁阻止事件处理程序写入控制台。它运行在另一个线程上,这是必要的,因为您使用的是不输出消息循环的控制台模式程序。SystemEvents类将创建自己的类来确保事件触发。这个被点赞的答案是错误的。
它尝试写入的内容最终会到达控制台,但这当然发生在控制台窗口关闭前一毫秒,所以您永远不会看到它。
这个新的4.5行为对快速测试程序来说意味着厄运。你需要一个更好的方法来决定你的程序是否已经完成,"按任意键继续"的方法已经不再有效了。一个不使用锁的蹩脚的替代方法是:
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(100);
UPDATE:此问题已在通过Windows UPDATE发布的。net 4.5更新中修复。我不太确定我是什么时候得到更新的,大概是2013年8月左右。
事件根本不被调用。在你的检查文档中,写着:
此事件仅在消息泵正在运行时引发。在Windows中服务,除非使用了隐藏表单或消息泵手动启动,此事件将不会引发。