Mengapa jendela konsol ditutup segera setelah ditampilkan output saya?


158

Saya mempelajari C # dengan mengikuti panduan di MSDN .

Sekarang, saya baru saja mencoba Contoh 1 (di sini adalah tautan ke MSDN ), dan saya mengalami masalah: mengapa jendela konsol segera ditutup setelah ditampilkan output saya?

using System;

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

Anda dapat mencoba membuka dengan konsol. Seret dan letakkan di konsol dan tekan "Enter". Saya menganggap ini file EXE.
Sajidur Rahman

Jika Anda mencoba untuk DEBUG program baris perintah yang dimulai oleh proses eksternal, lihat pertanyaan ini: stackoverflow.com/a/23334014/3195477
UuDdLrLrSs

Jawaban:


266

masalahnya di sini adalah bahwa Program Hello World mereka muncul maka itu akan segera ditutup.
mengapa demikian?

Karena sudah selesai. Ketika aplikasi konsol telah selesai dieksekusi dan kembali dari mainmetode mereka , jendela konsol terkait secara otomatis ditutup. Ini adalah perilaku yang diharapkan.

Jika Anda ingin tetap terbuka untuk keperluan debugging, Anda harus menginstruksikan komputer untuk menunggu penekanan tombol sebelum mengakhiri aplikasi dan menutup jendela.

The Console.ReadLineMetode adalah salah satu cara untuk melakukan itu. Menambahkan baris ini ke akhir kode Anda (tepat sebelum returnpernyataan) akan menyebabkan aplikasi menunggu Anda untuk menekan tombol sebelum keluar.

Sebagai alternatif, Anda dapat memulai aplikasi tanpa debugger dilampirkan dengan menekan Ctrl+ F5dari dalam lingkungan Visual Studio, tetapi ini jelas merugikan mencegah Anda menggunakan fitur debugging, yang mungkin Anda inginkan saat Anda menulis aplikasi.

Kompromi terbaik mungkin untuk memanggil Console.ReadLinemetode hanya ketika men-debug aplikasi dengan membungkusnya dalam arahan preprocessor. Sesuatu seperti:

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

Anda mungkin juga ingin jendela tetap terbuka jika pengecualian yang tidak tertangkap dilemparkan. Untuk melakukannya, Anda dapat meletakkannya Console.ReadLine();di finallyblok:

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

18
Bergantian, Anda dapat menggunakan Console.ReadKey ();
PlantationGator

55
Secara pribadi, saya lebih suka if (System.Diagnostics.Debugger.IsAttached) Console.ReadLine();.
Sameer Singh

5
Mengapa menjalankan tanpa men-debug mengubah perilaku itu? Anda akan berpikir itu harus pengalaman yang lebih akurat, bukan kurang.
Kyle Delaney

@SameerSingh Satu lagi baris kode yang tidak perlu dikompilasi ke dalam biner Anda. Saya sebenarnya lebih suka pendekatan preprosesor ini.
Joel

@ Joel Mengapa kita, secara umum, harus peduli tentang hal itu belakangan ini?
Alex

66

Alih-alih menggunakan

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

Anda dapat menjalankan program Anda menggunakan Ctrl+ F5(jika Anda berada di Visual Studio). Kemudian Visual Studio akan menjaga jendela konsol tetap terbuka, sampai Anda menekan tombol.

Catatan: Anda tidak dapat men-debug kode Anda dalam pendekatan ini.


Hai pengguna. Saya adalah pengguna baru untuk VS dan C # secara umum juga. Apa yang Ctrl + F5dilakukan secara berbeda yang cukup cantik Startlakukan secara berbeda?
theGreenCabbage

Sayangnya, terkadang berhenti berfungsi seperti yang diharapkan.
MaikoID

2
Penyebab masalahnya adalah bahwa windows secara otomatis menutup jendela terminal ketika program berhenti. Sistem lain akan membuat Jendela terbuka secara otomatis. Ini adalah cara yang jauh lebih baik untuk menjalankan program. Jangan gunakan ReadKey, Read atau ReadLine untuk hal ini karena ini mencegah program Anda digunakan dalam kombinasi dengan aplikasi konsol lainnya dan perpipaan.
realtime

14

Saya berasumsi alasan Anda tidak ingin menutupnya dalam mode Debug, adalah karena Anda ingin melihat nilai-nilai variabel dll. Jadi mungkin lebih baik memasukkan titik istirahat pada penutup "}" dari fungsi utama . Jika Anda tidak perlu men-debug, maka Ctrl-F5 adalah opsi terbaik.


Terkejut tidak ada jawaban lain yang menyarankan ini. Jarang jawaban dengan opsi baru ditambahkan begitu terlambat setelah pertanyaan dibuat.
Scott Chamberlain

13

Ini berlaku sama untuk CtrlF5atau F5. Tempatkan segera sebelum akhir Mainmetode.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

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

7
Sekadar diketahui, baris terakhir harus Console.ReadKey()untuk tombol apa pun, Console.ReadLine()menunggu masuk untuk ditekan
Chris

6

Program segera ditutup karena tidak ada yang menghentikannya dari penutupan. Masukkan breakpoint di return 0;atau tambahkan Console.Read();sebelum return 0;untuk mencegah program dari penutupan.


5

Saya sedikit terlambat ke pesta, tetapi: di Visual Studio 2019 untuk .NET Core memproyeksikan konsol tidak menutup secara otomatis secara default. Anda dapat mengkonfigurasi perilaku melalui menu Alat → Opsi → Debugging → Umum → Secara otomatis menutup konsol ketika debugging berhenti. Jika jendela konsol Anda secara otomatis ditutup, periksa apakah pengaturan yang disebutkan tidak diatur.

Hal yang sama berlaku untuk proyek konsol gaya baru .NET Framework:

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

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

</Project>

Proyek NET Framework. Gaya lama masih tanpa syarat menutup konsol di akhir (pada Visual Studio 16.0.1).

Referensi: https://devblogs.microsoft.com/dotnet/net-core-tooling-update-for-visual-studio-2019-preview-2/


Opsi ini tersedia untuk saya di VS2017 15.9.4 tetapi tidak berfungsi untuk aplikasi .net core 2.1 konsol saya ...
user1073075

@ user1073075: ini aneh. Apakah fitur tersebut berfungsi untuk target lain?
Vlad

Tidak. Mencoba dengan aplikasi .NET framework console dan masih tidak berfungsi. (Saya menginstal VS2019 pada mesin yang berbeda dan itu berfungsi. Mungkin itu adalah bug di VS17 15.9.4)
user1073075

Dengan 2019 sekarang berfungsi bahkan untuk proyek WPF: pastebin.com/FpAeV0cW . Tetapi Anda harus menginstal .NET Core 3.
Vlad

5

Jika Anda ingin aplikasi Anda tetap terbuka, Anda harus melakukan sesuatu agar prosesnya tetap hidup. Contoh di bawah ini adalah yang paling sederhana, untuk diletakkan di akhir program Anda:

while (true) ;

Namun, itu akan menyebabkan CPU kelebihan beban, karena itu dipaksa untuk mengulangi tanpa batas.

Pada titik ini, Anda dapat memilih untuk menggunakan System.Windows.Forms.Applicationkelas (tetapi mengharuskan Anda untuk menambahkan System.Windows.Formsreferensi):

Application.Run();

Ini tidak membocorkan CPU dan berhasil.

Untuk menghindari menambahkan System.Windows.Formsreferensi, Anda dapat menggunakan trik sederhana, yang disebut spin waiting , mengimpor System.Threading:

SpinWait.SpinUntil(() => false);

Ini juga berfungsi dengan baik, dan pada dasarnya terdiri dari whileloop dengan kondisi negated yang dikembalikan oleh metode lambda di atas. Mengapa CPU ini tidak kelebihan beban? Anda dapat melihat kode sumber di sini ; bagaimanapun, pada dasarnya menunggu beberapa siklus CPU sebelum iterasi.

Anda juga dapat membuat looper pesan, yang mengintip pesan yang tertunda dari sistem dan memproses masing-masing sebelum meneruskan ke iterasi berikutnya, sebagai berikut:

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

Kemudian, Anda dapat mengulang dengan aman dengan melakukan sesuatu seperti ini:

while (true)
    ProcessMessageOnce();

Saya tidak tahu apakah ini kebocoran CPU atau tidak tetapi; bekerja dengan sukses. Terima kasih.
Mumin Ka

4

Atau, Anda dapat menunda penutupan menggunakan kode berikut:

System.Threading.Thread.Sleep(1000);

Perhatikan Sleepmenggunakan milidetik.


4

Cara lain adalah menggunakan Debugger.Break()sebelum kembali dari metode Utama


Meskipun ini beralih fokus kembali ke jendela debugger dan berpotensi menyembunyikan konten jendela konsol.
Stephen Turner

3

Kode selesai, untuk melanjutkan Anda perlu menambahkan ini:

Console.ReadLine();

atau

Console.Read();

3

Gunakan Console.Read (); untuk mencegah program menutup, tetapi pastikan Anda menambahkan Console.Read();kode sebelum kembali pernyataan, atau itu akan menjadi kode yang tidak terjangkau.

    Console.Read(); 
    return 0; 

periksa Konsol ini. Baca


3

Tambahkan ReadMetode untuk menampilkan output.

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

1

Berikut adalah cara untuk melakukannya tanpa melibatkan Console:

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

0

Program ditutup segera setelah eksekusi selesai. Dalam hal ini saat Anda return 0;. Ini adalah fungsi yang diharapkan. Jika Anda ingin melihat outputnya, jalankan di terminal secara manual atau tunggu di akhir program agar tetap terbuka selama beberapa detik (menggunakan pustaka threading).


0

ini jawaban async di aplikasi konsol di C #?

apa pun di mana pun di aplikasi konsol tidak pernah digunakan awaittetapi gunakan theAsyncMethod().GetAwaiter().GetResult();,

contoh

var result = await HttpClientInstance.SendAsync(message);

menjadi

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


-3

jika program Anda mengharuskan Anda menekan enter untuk melanjutkan seperti Anda harus memasukkan nilai dan melanjutkan, kemudian tambahkan double atau int baru dan ketik write sebelum retunr (0); scanf_s ("% lf", & variabel);


1
Ini pertanyaan C # .
Wai Ha Lee

-3

Saya selalu menambahkan pernyataan berikut ke aplikasi konsol. (Buat cuplikan kode untuk ini jika Anda mau)

Console.WriteLine("Press any key to quit!");
Console.ReadKey();

Melakukan hal ini membantu ketika Anda ingin bereksperimen dengan berbagai konsep melalui aplikasi konsol.

Rkt + F5 akan membuat Konsol tetap tetapi Anda tidak dapat men-debug! Semua aplikasi konsol yang saya tulis di dunia nyata selalu non-interaktif dan dipicu oleh Penjadwal seperti stasiun TWS atau CA Work dan tidak memerlukan sesuatu seperti ini.


-3

Untuk menyederhanakan apa yang dikatakan orang lain: Gunakan Console.ReadKey();.

Ini membuatnya jadi program sedang menunggu pengguna untuk menekan tombol normal pada keyboard

Sumber: Saya menggunakannya dalam program saya untuk aplikasi konsol.


-3

Anda dapat menyelesaikannya dengan cara yang sangat sederhana hanya dengan memohon input. Namun, jika Anda menekan Entermaka konsol akan menghilang lagi. Cukup gunakan ini Console.ReadLine();atauConsole.Read();


-4

Tambahkan berikut ini sebelum kembali 0:

system("PAUSE");  

Ini mencetak garis untuk menekan tombol untuk menutup jendela. Ini akan menjaga jendela hingga Anda menekan tombol enter. Saya minta siswa saya menambahkannya ke semua program mereka.


1
thats di dalam c ++
Gonçalo Garrido

-13

Menurut kekhawatiran saya, jika kita ingin menstabilkan OUTPUT OF CONSOLE APPLICATION, sampai penutupan tampilan keluaran USE, label: setelah MainMethod, dan goto label; sebelum akhir program

Dalam Program.

misalnya:

static void Main(string[] args)
{
    label:

    // Snippet of code

    goto label;
}

2
Ini hanya akan menyebabkan program poster terus mencetak "Halo, Dunia!" berkali-kali
DavidPostill

1
Yesus Kristus, tidak tahu gotopernyataan bahkan diizinkan dalam bahasa C #.
Ch3shire
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.