为什么控制台窗口在显示我的输出后立即关闭?

我学习 C # 的方法是按照 MSDN中的指南。

现在,我刚刚尝试了 例子一(给你是到 MSDN的链接) ,我遇到了一个问题: 为什么一旦显示了我的输出,控制台窗口立即关闭?

using System;


public class Hello1
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}
405066 次浏览

程序一旦执行完毕就会关闭。

在这种情况下,当你 return 0;。这是预期的功能。

如果您想看到输出,那么可以手动在终端中运行它,或者在程序结束时设置等待,这样它将保持打开状态几秒钟(使用线程库)。

这里的问题是,他们的 Hello World 程序显示出来,然后它会立即关闭。
为什么?

因为已经结束了。当控制台应用程序完成执行并从其 main方法返回时,关联的控制台窗口将自动关闭。这是预料之中的行为。

如果为了调试的目的,你需要指示计算机在结束应用程序和关闭窗口之前等待一个按键。

Console.ReadLine是实现这一点的一种方法。将这一行添加到代码的末尾(就在 return语句之前)将导致应用程序等待您在退出之前按下一个键。

或者,您可以在 Visual Studio 环境中按下 Ctrl + F5来启动应用程序,而不需要附加调试器,但是这样做有一个明显的缺点,那就是阻止您使用调试功能,您可能希望在编写应用程序时使用这些功能。

最好的折衷方法可能是仅在调试应用程序时调用 Console.ReadLine方法,方法是在预处理器指令中包装该应用程序。比如:

#if DEBUG
Console.WriteLine("Press enter to close...");
Console.ReadLine();
#endif

如果抛出未捕获的异常,您可能还希望窗口保持打开状态。要做到这一点,你可以把 Console.ReadLine();放在一个 finally块:

#if DEBUG
try
{
//...
}
finally
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
#endif

程序立即关闭,因为没有什么能阻止它关闭。在 return 0;处插入断点或在 return 0;之前添加 Console.Read();,以防止程序关闭。

代码已完成,要继续,您需要添加以下内容:

Console.ReadLine();

或者

Console.Read();

添加 Read方法以显示输出。

Console.WriteLine("Hello, World!");
Console.Read();
return 0;

使用控制台。Read () ; 以防止程序关闭,但是请确保在返回语句之前添加 Console.Read();代码,否则它将是一个无法访问的代码。

    Console.Read();
return 0;

看看这个 控制台,读

而不是利用

Console.Readline()
Console.Read()
Console.ReadKey()

可以使用 Ctrl + F5运行程序(如果在 VisualStudio 中)。然后 VisualStudio 将保持控制台窗口处于打开状态,直到按下键为止。

注意: 不能用这种方法调试代码。

或者,您可以使用以下代码延迟关闭:

System.Threading.Thread.Sleep(1000);

注意,Sleep使用的是毫秒。

这对于 CtrlF5F5的行为是相同的。 立即放置在 Main方法结束之前。

using System.Diagnostics;


private static void Main(string[] args) {


DoWork();
  

if (Debugger.IsAttached) {
Console.WriteLine("Press any key to continue . . .");
Console.ReadKey();
}
}

另一种方法是在从 Main 方法返回之前使用 Debugger.Break()

我假设您不希望它在调试模式下关闭的原因,是因为您想查看变量的值等。所以最好在 main 函数的结束“}”上插入一个断点。 如果你不需要调试,那么 Ctrl-F5是最好的选择。

如果希望保持应用程序处于打开状态,则必须执行某些操作以保持其进程处于活动状态。下面的例子是最简单的一个,可以放在程序的最后:

while (true) ;

然而,它会导致 CPU 超载,因为它因此被迫无限迭代。

此时,您可以选择使用 System.Windows.Forms.Application类(但它需要您添加 System.Windows.Forms引用) :

Application.Run();

这不会泄漏 CPU 并且工作正常。

为了避免添加 System.Windows.Forms引用,可以使用一个简单的技巧,即所谓的 旋转等待,导入 System.Threading:

SpinWait.SpinUntil(() => false);

这也可以很好地工作,它基本上由一个带有否定条件的 while循环组成,该条件由上面的 lambda 方法返回。为什么这个 CPU 没有超载?您可以查看源代码 给你; 无论如何,它基本上在遍历之前等待一些 CPU 周期。

您还可以创建一个消息循环程序,它可以查看来自系统的挂起消息,并在传递到下一个迭代之前处理它们中的每一个,如下所示:

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "PeekMessage")]
public static extern int PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);


[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "GetMessage")]
public static extern int GetMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax);


[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "TranslateMessage")]
public static extern int TranslateMessage(ref NativeMessage lpMsg);


[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "DispatchMessage")]
public static extern int DispatchMessage(ref NativeMessage lpMsg);


[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode]
public static bool ProcessMessageOnce()
{
NativeMessage message = new NativeMessage();


if (!IsMessagePending(out message))
return true;


if (GetMessage(out message, IntPtr.Zero, 0, 0) == -1)
return true;


Message frameworkMessage = new Message()
{
HWnd = message.handle,
LParam = message.lParam,
WParam = message.wParam,
Msg = (int)message.msg
};


if (Application.FilterMessage(ref frameworkMessage))
return true;


TranslateMessage(ref message);
DispatchMessage(ref message);


return false;
}

然后,您可以通过执行以下操作来安全地进行循环:

while (true)
ProcessMessageOnce();

这就是答案: 在 C # 中的一个控制台应用中使用异步

控制台应用中的任何东西都不要使用 await而是使用 theAsyncMethod().GetAwaiter().GetResult();,

例子

var result = await HttpClientInstance.SendAsync(message);

变成了

var result = HttpClientInstance.SendAsync(message).GetAwaiter().GetResult();

这里有一种不涉及 Console的方法:

var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();

在 VisualStudio2019中用于。NET 核心项目控制台默认情况下不会自动关闭。您可以通过菜单工具→选项→调试→常规→调试停止时自动关闭控制台来配置行为。如果控制台窗口自动关闭,请检查是否未设置上述设置。

这同样适用于.NETFramework 新样式控制台项目:

<Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>


</Project>

老样式的.NET Framework 项目仍然在最后无条件地关闭控制台(从 Visual Studio 16.0.1开始)。

参考资料: Http://devblogs.microsoft.com/dotnet/NET-Core-tools-update-for-Visual-Studio-2019-view-2/”rel = “ nofollow noReferrer”> . NET Core tool update for Visual Studio 2019 Preview 2

工具-> 选项-> 调试-> 常规-> 自动关闭控制台(最后一个选项)

检查一下盒子,然后关上。

这适用于所有项目。