STA线程的基本要求 是它需要运行一条消息 泵。在Windows窗体中,您可以使用 Application.Run。或者你可以写 消息泵手动,使用 user32!GetMessage& DispatchMessage函数。 但它可能更容易使用 一个在WinForms或WPF中。
使用“user32 - > GetMessage”的程序的基本结构& “user32 - > DispatchMessage”?
答案 0 :(得分:3)
请参阅MSDN中的“使用消息和消息队列”主题(在Win32和COM开发>用户界面> Windows用户体验> Windows管理> Windows用户界面>窗口>消息和消息队列;您;可能需要查看同一部分中的其他文章和样本。快速摘要,省略错误处理并使用C语法而不是C#,原因如下所述:
RegisterClass(...);
CreateWindow(...);
ShowWindow(...); // probably not in your case
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
从窗口设置样板文件中可以看出,这仍然依赖于“静默窗口”,尽管是通过Win32 API而不是通过WinForms创建和消息传递的。所以你不是通过这种方式获得任何东西。因此,我感觉没有太多意义将这些内容转换为C# - 如果您的问题的唯一解决方案是一个不可见的窗口,您也可以使用一个不可见的Windows窗体和该平台附带的所有友好包装器。
但是,如果您实际上没有像链接问题的海报一样使用Windows窗体控件,那么您可以非常高兴地在控制台应用程序中使用.NET事件。对STA的限制和对消息泵的需求特定于从WinForms和ActiveX控件接收事件,如WebBrowser(或来自Win32 HWND的消息,但这不一定需要STA)。
答案 1 :(得分:0)
您想要处理哪些事件?设置消息泵将允许您处理Windows API消息。但由于这是一个控制台应用程序,我想不出任何感兴趣的Windows API消息。
我们倾向于将“事件”视为与Windows消息相关联,因为Windows窗体应用程序中的控件使用EventHandler委托响应用户输入,这些委托是为响应Windows API消息而调用的。但是,没有理由不能在控制台应用程序中使用委托;而且你不需要消息泵。您甚至可以使用EventHandler委托,尽管它看起来不合适,因为它不会对Windows API消息产生共鸣。
当然还有其他类型的“事件”你可能感兴趣。涉及控制台应用程序的最常见的事件场景是等待来自控制台的输入(stdin)。如果正在使用多个线程,则阻塞WaitHandle或其他同步对象也很常见。这两种情况都可以被视为一种事件处理。
如果您创建一个隐藏窗口(一个历史悠久的练习),您仍然需要一条Windows消息来响应。所以问题是:你想对什么或对谁做出回应?
答案 2 :(得分:0)
我会使用Application.Run方法。我不认为它会自动创建一个隐藏窗口,它只是抽取消息,这是满足STA要求所需的。
使用PInvoke编写自己的消息泵并没有提供任何优势,并且引用System.Windows.Forms并不是一个负担,因为它已经存在于您可能遇到的每台计算机上。