我正在按照MSDN中的指南学习C#。
现在,我只是尝试了示例1(这是指向MSDN的链接),但是我遇到了一个问题:为什么控制台窗口在显示我的输出后立即关闭?
using System;
public class Hello1
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}
我正在按照MSDN中的指南学习C#。
现在,我只是尝试了示例1(这是指向MSDN的链接),但是我遇到了一个问题:为什么控制台窗口在显示我的输出后立即关闭?
using System;
public class Hello1
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}
Answers:
这里的问题是他们的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
if (System.Diagnostics.Debugger.IsAttached) Console.ReadLine();
。
而不是使用
Console.Readline()
Console.Read()
Console.ReadKey()
您可以使用Ctrl+ F5(如果您在Visual Studio中)运行程序。然后,Visual Studio将保持控制台窗口打开,直到您按下一个键。
注意:您不能使用这种方法调试代码。
Ctrl + F5
做什么不同,单纯漂亮Start
有什么不同?
该程序立即关闭,因为没有什么可以阻止它关闭。在return 0;
或在Console.Read();
之前添加一个断点,return 0;
以防止程序关闭。
我参加聚会有点晚了,但是:在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开始)。
参考:https : //devblogs.microsoft.com/dotnet/net-core-tooling-update-for-visual-studio-2019-preview-2/
如果要保持打开应用程序的状态,则必须执行一些操作才能使其进程保持活动状态。下面的例子是最简单的例子,放在程序的末尾:
while (true) ;
但是,这将导致CPU过载,因为它被迫无限迭代。
在这一点上,您可以选择使用System.Windows.Forms.Application
类(但是它需要您添加System.Windows.Forms
引用):
Application.Run();
这不会泄漏CPU,并且可以成功运行。
为了避免添加System.Windows.Forms
引用,可以使用一个简单的技巧,即所谓的spin wait,import 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();
这是一种无需参与的方法Console
:
var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();
这是C#控制台应用程序上的答案异步吗?
控制台应用中的任何位置永远不会使用await
,而是使用theAsyncMethod().GetAwaiter().GetResult();
,
例
var result = await HttpClientInstance.SendAsync(message);
变成
var result = HttpClientInstance.SendAsync(message).GetAwaiter().GetResult();
您只需调用输入即可解决非常简单的方法。但是,如果按Enter
则控制台将再次消失。只需使用此Console.ReadLine();
或Console.Read();
根据我的担心,如果要稳定控制台应用程序的输出,直到输出关闭显示USE,在MainMethod之后贴上标签,然后转到goto标签;程序结束前
在程序中。
例如:
static void Main(string[] args)
{
label:
// Snippet of code
goto label;
}
goto
C#中是否允许声明。