web-dev-qa-db-ja.com

コンソールウィンドウに出力が表示されたらすぐに閉じるのはなぜですか。

MSDNのガイドに従ってC#を勉強しています。

さて、私は例1hereMSDNへのリンクです)を試したところ、問題:コンソールウィンドウが出力を表示したらすぐに閉じるのはなぜですか?

using System;

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

ここでの問題は、彼らのハローワールドプログラムが現れていて、それがすぐに閉じるということです。
何故ですか?

終了したためです。コンソールアプリケーションの実行が完了してmainメソッドから戻ると、関連するコンソールウィンドウは自動的に閉じます。これは予想される動作です。

デバッグ目的で開いたままにしておきたい場合は、アプリを終了してウィンドウを閉じる前に、キーを押すのを待つようにコンピュータに指示する必要があります。

Console.ReadLineメソッド がその1つの方法です。この行をコードの末尾(returnステートメントの直前)に追加すると、アプリケーションは終了する前にキーを押すのを待ちます。

あるいは、デバッガを接続せずにアプリケーションを起動することもできます。 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
249
Cody Gray

使用する代わりに

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

あなたが使用してあなたのプログラムを実行することができます Ctrl+F5 (あなたがVisual Studioにいるならば)。その後、キーを押すまで、Visual Studioはコンソールウィンドウを開いたままにします。

注:この方法ではコードをデバッグできません。

60
Bhavik Patel

これは同じ動作をします。 CtrlF5 または F5Mainメソッドの終わりの直前に置きます。

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

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

デバッグモードで閉じたくないのは、変数の値などを調べたいからです。メイン関数の最後の "}"にブレークポイントを挿入することをお勧めします。 。デバッグする必要がない場合は、Ctrl-F5が最善の選択肢です。

9
Rob L

閉じるのを止めるものは何もないので、プログラムはすぐに閉じます。プログラムが閉じないようにするには、return 0;にブレークポイントを挿入するか、return 0;の前にConsole.Read();を追加します。

6
Robert Rouhani

あるいは、次のコードを使用して終了を遅らせることができます。

System.Threading.Thread.Sleep(1000);

Sleepがミリ秒を使用していることに注意してください。

4
gotqn

アプリケーションを開いたままにしたい場合は、そのプロセスを有効に保つために何かをする必要があります。以下はプログラムの最後に置く最も簡単な例です。

while (true) ;

ただし、無限に繰り返すことを余儀なくされるため、CPUが過負荷になります。

この時点で、System.Windows.Forms.Applicationクラスを使用することを選択できます(ただし、System.Windows.Forms参照を追加する必要があります)。

Application.Run();

これはCPUをリークすることはなく、正常に動作します。

System.Windows.Forms参照を追加しないようにするために、単純なトリック、いわゆるスピン待機を使用して、System.Threadingをインポートすることができます。

SpinWait.SpinUntil(() => false);

これも完璧に機能し、主に上記のラムダメソッドによって返される否定条件を持つwhileイテレータで構成されています。なぜこの過負荷の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();

さらに良いことに、whileイテレータをSpinWait.SpinUntil呼び出しに置き換えることで、後者の2つの解決策を組み合わせることができます。

SpinWait.SpinUntil(ProcessMessageOnce);
4
Davide Cannizzo

別の方法は、Mainメソッドから戻る前にDebugger.Break()を使うことです

4
dimaaan

コードは完成しました。続行するには、これを追加する必要があります。

Console.ReadLine();

または

Console.Read();
3
Ari

出力を表示するためのReadメソッドを追加します。

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

Console.Read()を使用してください。プログラムが終了しないようにするには、returnステートメントの前にConsole.Read();コードを追加してください。そうしないと、到達不能コードになります。

    Console.Read(); 
    return 0; 

これを確認してください Console.Read

3
Ravi Gadag

私はパーティーに少し遅れていますが、.NET Coreプロジェクト用のVisual Studio 2019では、コンソールはデフォルトで自動的に閉じません。メニューの[ツール]→[オプション]→[デバッグ]→[全般]→[デバッグが停止したら自動的にコンソールを閉じる]を選択して、動作を設定できます。コンソールウィンドウが自動的に閉じられる場合は、上記の設定が設定されていないかどうかを確認してください。

同じことが.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/

1
Vlad

Consoleを使わずにこれを行う方法は次のとおりです。

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

実行が完了するとすぐにプログラムは終了します。この場合はreturn 0;とします。これは期待される機能です。出力を見たい場合は、端末で手動で実行するか、プログラムの最後に待機を設定して(スレッドライブラリを使用して)数秒間開いたままになるようにします。

0
zellio

これが答えです C#のコンソールアプリで非同期?

コンソールアプリ内のどこでもawaitを使用することはなく、代わりにtheAsyncMethod().GetAwaiter().GetResult();を使用します

var result = await HttpClientInstance.SendAsync(message);

になる

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

0
bresleveloper