たまたま知人より、キー入力を受け付けながら処理を行う事って出来るの??って聞かれたので
書いたサンプルです。もったいないので、メモメモ。
Console.ReadやConsole.ReadKeyメソッドは処理をブロックするので、そのまま処理のループの中で
呼んでしまうと制御が返ってこなくなります。
なので、キー入力を受け付ける処理を別のスレッドに分けて、メインとサブで
処理をするとすっきりします。
以下、殴り書きのサンプルです。
読みづらいです。すみません。
using System; using System.Threading; namespace Test { public class Sample { volatile static bool _keyReaded = false; static void Main() { ThreadPool.QueueUserWorkItem(new WaitCallback(MyHandler), null); for(;;) { if(_keyReaded) { Console.WriteLine("キーが押されました"); break; } Console.Write("Sleep in...."); Thread.Sleep(1000); Console.WriteLine("end."); } } static void MyHandler(object userState) { ConsoleKeyInfo keyInfo = Console.ReadKey(true); _keyReaded = true; } } }
当然、複数のスレッドが参照する_keyReaded変数は、volatileするかlockする必要があります。
補足)ちなみに、非同期デリゲートでも同じように出来ますね。
using System; using System.Threading; using System.Runtime.Remoting.Messaging; namespace Test { delegate ConsoleKeyInfo AsyncReadKey(bool displayChars); public class Sample { volatile static bool _keyReaded = false; static void Main() { new AsyncReadKey(Console.ReadKey).BeginInvoke(true, MyHandler, null); for(;;) { if(_keyReaded) { Console.WriteLine("キーが押されました"); break; } Console.Write("SLEEP IN...."); Thread.Sleep(TimeSpan.FromSeconds(1)); Console.WriteLine("END"); } } static void MyHandler(IAsyncResult ar) { AsyncResult asyncResult = (AsyncResult) ar; AsyncReadKey asyncDelegate = (AsyncReadKey) asyncResult.AsyncDelegate; ConsoleKeyInfo keyInfo = asyncDelegate.EndInvoke(asyncResult); _keyReaded = true; } } }
さらについでに、自前でデリゲートを切らずにフレームワーク付属の汎用デリゲートを利用した版
using System; using System.Threading; using System.Runtime.Remoting.Messaging; namespace Test { public class Sample { volatile static bool _keyReaded = false; static void Main() { new Func<bool, ConsoleKeyInfo>(Console.ReadKey).BeginInvoke(true, MyHandler, null); for(;;) { if(_keyReaded) { Console.WriteLine("キーが押されました"); break; } Console.Write("SLEEP IN...."); Thread.Sleep(TimeSpan.FromSeconds(1)); Console.WriteLine("END"); } } static void MyHandler(IAsyncResult ar) { AsyncResult asyncResult = (AsyncResult) ar; Func<bool, ConsoleKeyInfo> asyncDelegate = (Func<bool, ConsoleKeyInfo>) asyncResult.AsyncDelegate; ConsoleKeyInfo keyInfo = asyncDelegate.EndInvoke(asyncResult); _keyReaded = true; } } }
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場