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;
}
}
回答:
ここでの問題は、Hello Worldプログラムが表示され、すぐに終了することです。
何故ですか?
終わったから。コンソールアプリケーションの実行が完了してmain
メソッドから戻ると、関連するコンソールウィンドウが自動的に閉じます。これは予想される動作です。
デバッグのために開いたままにする場合は、アプリを終了してウィンドウを閉じる前に、キーを押すのを待つようにコンピューターに指示する必要があります。
このConsole.ReadLine
方法は、そのための1つの方法です。この行をコードの最後(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
異なりますか?
デバッグモードで閉じたくない理由は、変数の値などを見たいからだと思います。したがって、メイン関数の閉じる "}"にブレークポイントを挿入するのがおそらく最善です。 。デバッグする必要がない場合は、Ctrl-F5が最適なオプションです。
これがために同じ動作をしますCtrlF5かF5。Main
メソッドの終了直前に配置します。
using System.Diagnostics;
private static void Main(string[] args) {
DoWork();
if (Debugger.IsAttached) {
Console.WriteLine("Press any key to continue . . .");
Console.ReadLine();
}
}
Console.ReadKey()
任意のキーConsole.ReadLine()
用で、Enter キーが押されるのを待ちます
パーティーには少し遅れますが、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
参照の追加を避けるために、単純なトリック、いわゆるスピンウェイティングを使用してインポートできSystem.Threading
ます。
SpinWait.SpinUntil(() => false);
これも完全に機能し、基本的にはwhile
上記のラムダメソッドによって返される否定条件のループで構成されます。なぜこの過負荷な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();
別の方法はDebugger.Break()
、Mainメソッドから戻る前に使用することです
これは関与せずにそれを行う方法ですConsole
:
var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();
これはC#のコンソールアプリで非同期の答えですか?
何でもwhereeverコンソールアプリで使用することはありませんawait
が、代わりに使用しtheAsyncMethod().GetAwaiter().GetResult();
、
例
var result = await HttpClientInstance.SendAsync(message);
なる
var result = HttpClientInstance.SendAsync(message).GetAwaiter().GetResult();
値を入力して続行する必要がある場合と同様に、プログラムでEnterキーを押して続行する必要がある場合は、新しいdoubleまたはintを追加し、retunr(0)の前にwriteと入力します。scanf_s( "%lf"、&the変数);
私は常に次のステートメントをコンソールアプリケーションに追加します(必要に応じて、このためのコードスニペットを作成します)。
Console.WriteLine("Press any key to quit!");
Console.ReadKey();
これは、コンソールアプリケーションを使用してさまざまな概念を試したい場合に役立ちます。
Ctr + F5はコンソールを維持しますが、デバッグできません!私が実際に作成したすべてのコンソールアプリケーションは、常に非対話型で、TWSやCAワークステーションなどのスケジューラーによってトリガーされ、このようなものを必要としませんでした。
他の人が言っていることを単純化するには:を使用しConsole.ReadKey();
ます。
これにより、プログラムはユーザーがキーボードの通常のキーを押すのを待機します。
出典:コンソールアプリケーションのプログラムで使用しています。
入力を呼び出すだけで非常に簡単な方法で解決できます。ただし、を押すEnter
と、コンソールが再び消えます。単にこれを使用するConsole.ReadLine();
か、Console.Read();
私の懸念によると、出力のコンソールアプリケーションを安定させるには、出力が閉じるまでUSE、ラベル:MainMethodの後、およびgotoラベルを表示します。プログラム終了前
プログラム内。
例えば:
static void Main(string[] args)
{
label:
// Snippet of code
goto label;
}
goto
C#で許可されている発言さえ知らなかった。