为什么C#控制台应用程序可以调用`Application.Run()`?

5

我看到几个控制台应用程序调用了 Application.Run(), 它会在当前线程上启动一个没有窗体的消息循环。

https://msdn.microsoft.com/en-us/library/ms157900(v=vs.110).aspx

然而,正如文档所述:

在基于 Win32 或 Windows Forms 的应用程序中,消息循环是处理用户事件(例如鼠标单击和键盘敲击)的代码例程。

因此,似乎只有 GUI 应用程序才适用于 Application.Run()

那么在控制台应用程序中调用 Application.Run() 的目的是什么?是否有更聪明的方法在控制台应用程序中实现相同的功能?


为什么你会说这只适用于GUI应用程序?它同样适用于控制台应用程序,因为它们也可以很好地实现消息循环。 - Timothy Groote
但是,我已经创建了很多控制台应用程序而没有调用Application.Run()。文档说:“每个正在运行的基于Windows的应用程序都需要一个活动的消息循环”。 - Shuzheng
1
"什么是目的[...]是否有更聪明的方法?" - 然后展示或链接到这些例子。有无数的原因可以选择这样做,以及同样多的替代方案,使这个问题过于广泛。 - CodeCaster
1
@CodeCaster - https://hinchley.net/articles/creating-a-key-logger-via-a-global-system-hook-using-powershell/ - Shuzheng
它在构建GUI应用程序时通常是明智的选择(大多数情况下),但这并不意味着在其他地方使用它是一个坏主意。 - Timothy Groote
显示剩余6条评论
1个回答

8

你必须看到更大的图景,是创建窗口而不是Application.Run()创建GUI应用程序。支持窗口的类库以及与之交互的许多系统和第三方组件从未线程安全。但GUI必须始终处理来自不同线程(通常位于不同进程或操作系统中)生成的通知。

这是一个棘手的问题,但它在软件工程中非常普遍,并且有一个通用的解决方案,你必须解决生产者消费者问题。这需要一个线程安全的队列,由操作系统提供。并且需要一个循环来清空该队列并分派通知,这就是Application.Run()的作用。

此外,将代码运行在特定线程上的唯一实用方法是使用调度程序循环。这似乎应该很容易做到,但事实并非如此。线程总是忙于执行代码,您不能随意中断它并强制其执行其他操作,否则会产生可怕的重入问题。调度程序循环是线程信号空闲且准备好执行其他操作的安全位置。这可能是您在控制台模式应用程序中看到它被使用的原因。特别是当您在该代码中看到异步/等待时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接