vezel-dev / cathode

A terminal-centric replacement for the .NET console APIs.
https://docs.vezel.dev/cathode
BSD Zero Clause License
91 stars 7 forks source link

Handle cancellation of `TextReader`/`TextWriter` access resiliently #111

Open alexrp opened 1 year ago

alexrp commented 1 year ago

The TextReader/TextWriter and Stream properties exposed on the TerminalReader/TerminalWriter and TerminalHandle classes, respectively, are meant to be long-lived and resilient. For the Stream property, this works as expected; disposal does nothing and cancellation has no lasting effect (other than potentially losing some input/output that was scheduled).

Unfortunately, System.IO.StreamReader/System.IO.StreamWriter are not guaranteed to be in a valid state after a cancellation has occurred. This means that our properties can be rendered unusable if the user ever performs cancellation.

The main reason we have these properties is line-based input:

https://github.com/vezel-dev/cathode/blob/695b2970bf95aaa2756eebb5e7641b8834a9e234/src/core/IO/TerminalReader.cs#L69-L77

(Other than the above, these properties are not used in Cathode itself.)

The only solution I see here is to implement our own derived System.IO.TextReader/System.IO.TextWriter classes specialized for our needs. We can then do whatever we need to do to keep the state valid across cancellations.