-
Notifications
You must be signed in to change notification settings - Fork 0
Thread Safety
Sharpie, and its underlying NCurses
library is inherently not thread-safe. Any two concurrent operations performed on Sharpie objects can result in undefined behavior. By default, when using Sharpie that is the behavior you get.
For example, assume the following (clearly illustrative) code:
using var terminal = new Terminal(NativeCursesProvider.Instance, new());
Task.Run(() => terminal.Screen.WriteText("Hello"));
Task.Run(() => terminal.Screen.WriteText("World"));
Task.Run(() => terminal.Screen.Refresh());
This code will likely result in strange artifacts on the screen as all three parallel tasks try to manipulate the screen simultaneously. Now, this is a very simple and obviously-avoidable example, but in sophisticated applications with multiple UI elements and modules, it is hard to maintain multi-threaded correctness.
This is where Terminal.Run
comes into the picture. Application developers are encouraged to use this facility to transition the library into synchronized mode.
For example, the same code can be rewritten as:
using var terminal = new Terminal(NativeCursesProvider.Instance, new());
terminal.Run((t, e) => {
if (e is StartEvent)
{
t.Delegate(() => t.Screen.WriteText("Hello"));
t.Delegate(() => t.Screen.WriteText("World"));
t.Delegate(() => t.Screen.Refresh());
}
return Task.CompletedTask;
});
Yes, I know the example is not the best one, but what it shows is that Terminal.Run
blocks the executing thread and executes all operations in a synchronized manner, thus avoiding any overlap and race conditions. The Terminal.Delegate
method pushes an action to be executed in a synchronized manner.