Mengatasi kasus-kasus yang beberapa jawaban lainnya tidak ditangani dengan baik:
- Responsif : eksekusi langsung kode penanganan penekanan tombol; menghindari keanehan polling atau memblokir penundaan
- Opsionalitas : penekanan tombol global adalah opt-in ; jika tidak, aplikasi akan keluar secara normal
- Pemisahan masalah : kode pendengaran yang kurang invasif; beroperasi secara independen dari kode aplikasi konsol normal.
Banyak solusi di halaman ini melibatkan polling Console.KeyAvailable
atau pemblokiran Console.ReadKey
. Meskipun memang benar. NET Console
tidak terlalu kooperatif di sini, Anda dapat menggunakan Task.Run
untuk beralih ke Async
mode mendengarkan yang lebih modern .
Masalah utama yang harus diperhatikan adalah bahwa, secara default, utas konsol Anda tidak diatur untuk Async
operasi - artinya, ketika Anda keluar dari bagian bawah main
fungsi Anda , alih-alih menunggu Async
penyelesaian, AppDoman Anda dan prosesnya akan berakhir . Cara yang tepat untuk mengatasinya adalah dengan menggunakan AsyncContext karya Stephen Cleary untuk membangun Async
dukungan penuh dalam program konsol single-threaded Anda. Tetapi untuk kasus yang lebih sederhana, seperti menunggu penekanan tombol, memasang trampolin penuh mungkin berlebihan.
Contoh di bawah ini adalah untuk program konsol yang digunakan dalam beberapa jenis file batch berulang. Dalam hal ini, ketika program selesai dengan pekerjaannya, biasanya ia harus keluar tanpa perlu menekan tombol, dan kemudian kami mengizinkan penekanan tombol opsional untuk mencegah aplikasi keluar. Kita dapat menjeda siklus untuk memeriksa hal-hal, mungkin melanjutkan, atau menggunakan jeda sebagai 'titik kontrol' yang dikenal di mana untuk membersihkan file batch.
static void Main(String[] args)
{
Console.WriteLine("Press any key to prevent exit...");
var tHold = Task.Run(() => Console.ReadKey(true));
// ... do your console app activity ...
if (tHold.IsCompleted)
{
#if false // For the 'hold' state, you can simply halt forever...
Console.WriteLine("Holding.");
Thread.Sleep(Timeout.Infinite);
#else // ...or allow continuing to exit
while (Console.KeyAvailable)
Console.ReadKey(true); // flush/consume any extras
Console.WriteLine("Holding. Press 'Esc' to exit.");
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
;
#endif
}
}