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.KeyAvailableatau pemblokiran Console.ReadKey. Meskipun memang benar. NET Consoletidak terlalu kooperatif di sini, Anda dapat menggunakan Task.Rununtuk beralih ke Asyncmode mendengarkan yang lebih modern .
Masalah utama yang harus diperhatikan adalah bahwa, secara default, utas konsol Anda tidak diatur untuk Asyncoperasi - artinya, ketika Anda keluar dari bagian bawah mainfungsi Anda , alih-alih menunggu Asyncpenyelesaian, AppDoman Anda dan prosesnya akan berakhir . Cara yang tepat untuk mengatasinya adalah dengan menggunakan AsyncContext karya Stephen Cleary untuk membangun Asyncdukungan 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
}
}