Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IObservable of keys pressed

So I can experiment with Reactive Extensions, I'd like to create an IObservable of keys pressed by the user. How can I do this?

This is for a C# console application

like image 916
Colonel Panic Avatar asked Nov 29 '25 16:11

Colonel Panic


2 Answers

Try this to get an observable sequence of read keys:

        IObservable<System.ConsoleKeyInfo> keys =
            Observable
                .Defer(() =>
                    Observable
                        .Start(() =>
                            Console.ReadKey()))
                .Repeat();

I tested this and it worked like a treat.

like image 79
Enigmativity Avatar answered Dec 02 '25 05:12

Enigmativity


The blocking versions of ReadKey() have a problem, in that if you dispose the subscription, it still prompts you to press a key.

If you want to have a clean unsubscription, i.e, be able to cancel the prompt, it's (unfortunately) necessary to go with a polling approach.

Observable.Interval(TimeSpan.FromMilliseconds(100))
          .Where(_ => Console.KeyAvailable)
          .Select(_ => (char)Console.ReadKey(false).Key)

You can now do cool things like Amb this stream with Observable.Timer to set up a timeout for keypresses.

like image 41
Asti Avatar answered Dec 02 '25 05:12

Asti