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

发布于 2024-12-26 23:39:32 字数 370 浏览 3 评论 0原文

我正在按照 MSDN 中的指南学习 C#。

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

using System;

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

I'm studying C# by following the guides in MSDN.

Now, I just tried the Example 1 (here is the link to MSDN), and I've encountered an issue: why is the console window closing immediately once displayed my output?

using System;

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

伤痕我心 2025-01-02 23:39:32

这里的问题是他们的 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

the issue here is that their Hello World Program is showing up then it would immediately close.
why is that?

Because it's finished. When console applications have completed executing and return from their main method, the associated console window automatically closes. This is expected behavior.

If you want to keep it open for debugging purposes, you'll need to instruct the computer to wait for a key press before ending the app and closing the window.

The Console.ReadLine method is one way of doing that. Adding this line to the end of your code (just before the return statement) will cause the application to wait for you to press a key before exiting.

Alternatively, you could start the application without the debugger attached by pressing Ctrl+F5 from within the Visual Studio environment, but this has the obvious disadvantage of preventing you from using the debugging features, which you probably want at your disposal when writing an application.

The best compromise is probably to call the Console.ReadLine method only when debugging the application by wrapping it in a preprocessor directive. Something like:

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

You might also want the window to stay open if an uncaught exception was thrown. To do that you can put the Console.ReadLine(); in a finally block:

#if DEBUG
    try
    {
        //...
    }
    finally
    {
        Console.WriteLine("Press enter to close...");
        Console.ReadLine();
    }
#endif
情感失落者 2025-01-02 23:39:32

而不是使用

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

您可以使用 Ctrl+F5 (如果您在 Visual Studio 中)运行程序, 。然后 Visual Studio 将保持控制台窗口打开,直到您按下某个键。

注意:您无法用这种方法调试代码。

Instead of using

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

you can run your program using Ctrl+F5 (if you are in Visual Studio). Then Visual Studio will keep the console window open, until you press a key.

Note: You cannot debug your code in this approach.

蘑菇王子 2025-01-02 23:39:32

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

I assume the reason you don't want it to close in Debug mode, is because you want to look at the values of variables etc. So it's probably best to just insert a break-point on the closing "}" of the main function.
If you don't need to debug, then Ctrl-F5 is the best option.

抚笙 2025-01-02 23:39:32

CtrlF5F5 的行为相同。
放置在 Main 方法末尾之前。

using System.Diagnostics;

private static void Main(string[] args) {

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

This behaves the same for CtrlF5 or F5.
Place immediately before end of Main method.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();
  
  if (Debugger.IsAttached) {
    Console.WriteLine("Press any key to continue . . .");
    Console.ReadKey();
  }
}
抠脚大汉 2025-01-02 23:39:32

在 Visual Studio 2019 for .NET Core 项目中,控制台默认不会自动关闭。您可以通过菜单“工具”→“选项”→“调试”→“常规”→“调试停止时自动关闭控制台”来配置行为。如果控制台窗口自动关闭,请检查是否未设置上述设置。

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

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

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

</Project>

旧样式 .NET Framework 项目最终仍然无条件关闭控制台(从 Visual Studio 16.0.1 开始)。

参考:。 Visual Studio 2019 Preview 2 的 NET Core 工具更新

In Visual Studio 2019 for .NET Core projects the console doesn't close automatically by default. You can configure the behaviour through menu Tools → Options → Debugging → General → Automatically close the console when debugging stops. If you get your console window automatically closing, check if the mentioned setting is not set.

The same applies to the .NET Framework new style console projects:

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

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

</Project>

The old style .NET Framework project still unconditionally close the console at the end (as of Visual Studio 16.0.1).

Reference: .NET Core tooling update for Visual Studio 2019 Preview 2

追星践月 2025-01-02 23:39:32

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

The program immediately closes because there's nothing stopping it from closing. Insert a breakpoint at return 0; or add Console.Read(); before return 0; to prevent the program from closing.

柳絮泡泡 2025-01-02 23:39:32

如果你想让你的应用程序保持打开状态,你必须做一些事情来保持它的进程处于活动状态。下面的例子是最简单的例子,可以放在程序的末尾:

while (true) ;

但是,它会导致 CPU 过载,因为它因此被迫无限迭代。

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

Application.Run();

这并不泄漏CPU并且工作成功。

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

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();

If you want to keep your application opened, you have to do something in order to keep its process alive. The below example is the simplest one, to be put at the end of your program:

while (true) ;

However, it'll cause the CPU to overload, as it's therefore forced to iterate infinitely.

At this point, you can opt to use System.Windows.Forms.Application class (but it requires you to add System.Windows.Forms reference):

Application.Run();

This doesn't leak CPU and works successfully.

In order to avoid to add System.Windows.Forms reference, you can use a simple trick, the so-called spin waiting, importing System.Threading:

SpinWait.SpinUntil(() => false);

This also works perfectly, and it basically consists of a while loop with a negated condition that is returned by the above lambda method. Why isn't this overloading CPU? You can look at the source code here; anyway, it basically waits some CPU cycle before iterating over.

You can also create a message looper, which peeks the pending messages from the system and processes each of them before passing to the next iteration, as follows:

[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;
}

Then, you can loop safely by doing something like this:

while (true)
    ProcessMessageOnce();
森末i 2025-01-02 23:39:32

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

Console.ReadLine();

Console.Read();

The code is finished, to continue you need to add this:

Console.ReadLine();

or

Console.Read();
梦里兽 2025-01-02 23:39:32

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

System.Threading.Thread.Sleep(1000);

请注意,Sleep 使用毫秒。

Alternatively, you can delay the closing using the following code:

System.Threading.Thread.Sleep(1000);

Note the Sleep is using milliseconds.

生死何惧 2025-01-02 23:39:32

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

Another way is to use Debugger.Break() before returning from Main method

無處可尋 2025-01-02 23:39:32

使用 Console.Read();防止程序关闭,但一定要在 return 语句之前添加 Console.Read(); 代码,否则将是无法访问的代码。

    Console.Read(); 
    return 0; 

检查这个Console.Read

Use Console.Read(); to prevent the program from closing, but make sure you add the Console.Read(); code before return statement, or else it will be a unreachable code .

    Console.Read(); 
    return 0; 

check this Console.Read

甲如呢乙后呢 2025-01-02 23:39:32

添加 Read 方法以显示输出。

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

Add The Read method to show the output.

Console.WriteLine("Hello, World!");
Console.Read();
return 0;
岁月流歌 2025-01-02 23:39:32

这是一种不涉及 Console 的方法:

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

Here is a way to do it without involving Console:

var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();
末が日狂欢 2025-01-02 23:39:32

工具 ->选项->调试->一般->自动关闭控制台(倒数第五个选项)

选中该框并关闭。

这适用于所有项目。

Tools -> Options -> Debugging -> General -> Automatically close the console (5th last option)

Check the box and close.

This applied to all projects.

眸中客 2025-01-02 23:39:32

程序执行完成后立即关闭。

在这种情况下,当您返回 0; 时。这是预期的功能。

如果您想查看输出,则可以在终端中手动运行它,或者在程序末尾设置等待,以便它将保持打开状态几秒钟(使用线程库)。

The program is closing as soon as its execution is complete.

In this case when you return 0;. This is expected functionality.

If you want to see the output then either run it in a terminal manually or set a wait at the end of the program so that it will stay open for a few seconds (using the threading library).

我一向站在原地 2025-01-02 23:39:32

这对我有用:

Console.ReadKey(); 

This is worked for me:

Console.ReadKey(); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文