diff --git a/docs/input/live/index.cshtml b/docs/input/live/index.cshtml
new file mode 100644
index 0000000..d6b660a
--- /dev/null
+++ b/docs/input/live/index.cshtml
@@ -0,0 +1,12 @@
+Title: Live Displays
+Order: 4
+---
+
+
Sections
+
+
+@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
+{
+  - @Html.DocumentLink(child)+}
+
\ No newline at end of file
diff --git a/docs/input/progress.md b/docs/input/live/progress.md
similarity index 79%
rename from docs/input/progress.md
rename to docs/input/live/progress.md
index 6fe2978..369dd1e 100644
--- a/docs/input/progress.md
+++ b/docs/input/live/progress.md
@@ -1,16 +1,23 @@
 Title: Progress
 Order: 5
+RedirectFrom: progress
 ---
 
 Spectre.Console can display information about long running tasks in the console. 
 
- +
+ +
+
+
+
+   The progress display is not 
+  thread safe, and using it together with other interactive components such as 
+  prompts, status displays or other progress displays are not supported.
+
 
 If the current terminal isn't considered "interactive", such as when running 
 in a continuous integration system, or the terminal can't display 
 ANSI control sequence, any progress will be displayed in a simpler way.
 
- +
+ # Usage
 
diff --git a/docs/input/status.md b/docs/input/live/status.md
similarity index 77%
rename from docs/input/status.md
rename to docs/input/live/status.md
index 8ad0307..1508c0e 100644
--- a/docs/input/status.md
+++ b/docs/input/live/status.md
@@ -1,10 +1,17 @@
 Title: Status
 Order: 6
+RedirectFrom: status
 ---
 
 Spectre.Console can display information about long running tasks in the console. 
 
-
 
 # Usage
 
diff --git a/docs/input/status.md b/docs/input/live/status.md
similarity index 77%
rename from docs/input/status.md
rename to docs/input/live/status.md
index 8ad0307..1508c0e 100644
--- a/docs/input/status.md
+++ b/docs/input/live/status.md
@@ -1,10 +1,17 @@
 Title: Status
 Order: 6
+RedirectFrom: status
 ---
 
 Spectre.Console can display information about long running tasks in the console. 
 
- +
+ +
+
+
+
+   The status display is not 
+  thread safe, and using it together with other interactive components such as 
+  prompts, progress displays or other status displays are not supported.
+
 
 If the current terminal isn't considered "interactive", such as when running 
 in a continuous integration system, or the terminal can't display 
diff --git a/docs/input/prompts/multiselection.md b/docs/input/prompts/multiselection.md
index d5ed617..0591cbe 100644
--- a/docs/input/prompts/multiselection.md
+++ b/docs/input/prompts/multiselection.md
@@ -7,6 +7,11 @@ one or many items from a provided list.
 
  +
 
+
+   The use of prompts 
+  insides status or progress displays is not supported.
+
+
 # Usage
 
 ```csharp
diff --git a/docs/input/prompts/selection.md b/docs/input/prompts/selection.md
index 620b0e8..535919e 100644
--- a/docs/input/prompts/selection.md
+++ b/docs/input/prompts/selection.md
@@ -7,6 +7,11 @@ a single item from a provided list.
 
  +
 
+
+   Using prompts inside 
+  status or progress displays, are not supported.
+
+
 # Usage
 
 ```csharp
diff --git a/docs/input/prompts/text.md b/docs/input/prompts/text.md
index 9fb65e7..59d0409 100644
--- a/docs/input/prompts/text.md
+++ b/docs/input/prompts/text.md
@@ -1,4 +1,4 @@
-Title: Text
+Title: Text prompt
 Order: 0
 RedirectFrom: prompt
 ---
@@ -6,6 +6,11 @@ RedirectFrom: prompt
 Sometimes you want to get some input from the user, and for this
 you can use the `Prompt`.
 
+
+   The use of prompts 
+  insides status or progress displays is not supported.
+
+
 # Confirmation
 
 ```csharp
diff --git a/dotnet-tools.json b/dotnet-tools.json
index 720fc54..86e2bc7 100644
--- a/dotnet-tools.json
+++ b/dotnet-tools.json
@@ -3,7 +3,7 @@
   "isRoot": true,
   "tools": {
     "cake.tool": {
-      "version": "1.0.0-rc0002",
+      "version": "1.1.0",
       "commands": [
         "dotnet-cake"
       ]
diff --git a/examples/Console/Prompt/Program.cs b/examples/Console/Prompt/Program.cs
index 2dc5127..0c716c2 100644
--- a/examples/Console/Prompt/Program.cs
+++ b/examples/Console/Prompt/Program.cs
@@ -59,6 +59,7 @@ namespace Cursor
                 new MultiSelectionPrompt()
                     .PageSize(10)
                     .Title("What are your [green]favorite fruits[/]?")
+                    .MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
                     .InstructionsText("[grey](Press [blue][/] to toggle a fruit, [green][/] to accept)[/]")
                     .AddChoices(new[]
                     {
@@ -75,6 +76,7 @@ namespace Cursor
                 fruit = AnsiConsole.Prompt(
                     new SelectionPrompt()
                         .Title("Ok, but if you could only choose [green]one[/]?")
+                        .MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
                         .AddChoices(favorites));
             }
 
diff --git a/src/Spectre.Console.Testing/Fakes/FakeAnsiConsole.cs b/src/Spectre.Console.Testing/Fakes/FakeAnsiConsole.cs
index c692b20..1f3cab0 100644
--- a/src/Spectre.Console.Testing/Fakes/FakeAnsiConsole.cs
+++ b/src/Spectre.Console.Testing/Fakes/FakeAnsiConsole.cs
@@ -9,12 +9,14 @@ namespace Spectre.Console.Testing
     {
         private readonly StringWriter _writer;
         private readonly IAnsiConsole _console;
+        private readonly FakeExclusivityMode _exclusivityLock;
 
         public string Output => _writer.ToString();
 
         public Profile Profile => _console.Profile;
         public IAnsiConsoleCursor Cursor => _console.Cursor;
         public FakeConsoleInput Input { get; }
+        public IExclusivityMode ExclusivityMode => _exclusivityLock;
         public RenderPipeline Pipeline => _console.Pipeline;
 
         IAnsiConsoleInput IAnsiConsole.Input => Input;
@@ -24,6 +26,7 @@ namespace Spectre.Console.Testing
             AnsiSupport ansi = AnsiSupport.Yes,
             int width = 80)
         {
+            _exclusivityLock = new FakeExclusivityMode();
             _writer = new StringWriter();
 
             var factory = new AnsiConsoleFactory();
diff --git a/src/Spectre.Console.Testing/Fakes/FakeConsole.cs b/src/Spectre.Console.Testing/Fakes/FakeConsole.cs
index 183d916..0bd53cc 100644
--- a/src/Spectre.Console.Testing/Fakes/FakeConsole.cs
+++ b/src/Spectre.Console.Testing/Fakes/FakeConsole.cs
@@ -12,6 +12,7 @@ namespace Spectre.Console.Testing
         public Profile Profile { get; }
         public IAnsiConsoleCursor Cursor => new FakeAnsiConsoleCursor();
         IAnsiConsoleInput IAnsiConsole.Input => Input;
+        public IExclusivityMode ExclusivityMode { get; }
         public RenderPipeline Pipeline { get; }
 
         public FakeConsoleInput Input { get; }
@@ -24,6 +25,7 @@ namespace Spectre.Console.Testing
             bool legacyConsole = false, bool interactive = true)
         {
             Input = new FakeConsoleInput();
+            ExclusivityMode = new FakeExclusivityMode();
             Pipeline = new RenderPipeline();
 
             Profile = new Profile(new StringWriter(), encoding ?? Encoding.UTF8);
diff --git a/src/Spectre.Console.Testing/Fakes/FakeExclusivityMode.cs b/src/Spectre.Console.Testing/Fakes/FakeExclusivityMode.cs
new file mode 100644
index 0000000..ffb98e7
--- /dev/null
+++ b/src/Spectre.Console.Testing/Fakes/FakeExclusivityMode.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Spectre.Console.Testing
+{
+    public sealed class FakeExclusivityMode : IExclusivityMode
+    {
+        public T Run(Func func)
+        {
+            return func();
+        }
+
+        public async Task Run(Func> func)
+        {
+            return await func();
+        }
+    }
+}
diff --git a/src/Spectre.Console/AnsiConsoleFactory.cs b/src/Spectre.Console/AnsiConsoleFactory.cs
index 9b060a9..cb4d541 100644
--- a/src/Spectre.Console/AnsiConsoleFactory.cs
+++ b/src/Spectre.Console/AnsiConsoleFactory.cs
@@ -2,6 +2,7 @@ using System;
 using System.Runtime.InteropServices;
 using System.Text;
 using Spectre.Console.Enrichment;
+using Spectre.Console.Internal;
 
 namespace Spectre.Console
 {
@@ -58,7 +59,9 @@ namespace Spectre.Console
                 settings.Enrichment,
                 settings.EnvironmentVariables);
 
-            return new AnsiConsoleFacade(profile);
+            return new AnsiConsoleFacade(
+                profile,
+                settings.ExclusivityMode ?? new DefaultExclusivityMode());
         }
 
         private static (bool Ansi, bool Legacy) DetectAnsi(AnsiConsoleSettings settings, System.IO.TextWriter buffer)
diff --git a/src/Spectre.Console/AnsiConsoleSettings.cs b/src/Spectre.Console/AnsiConsoleSettings.cs
index 2027872..e847481 100644
--- a/src/Spectre.Console/AnsiConsoleSettings.cs
+++ b/src/Spectre.Console/AnsiConsoleSettings.cs
@@ -30,6 +30,11 @@ namespace Spectre.Console
         /// 
         public InteractionSupport Interactive { get; set; }
 
+        /// 
+        /// Gets or sets the exclusivity mode.
+        /// 
+        public IExclusivityMode? ExclusivityMode { get; set; }
+
         /// 
         /// Gets or sets the profile enrichments settings.
         /// 
diff --git a/src/Spectre.Console/Cli/FlagValue.cs b/src/Spectre.Console/Cli/FlagValue.cs
index a1989bc..9ae8845 100644
--- a/src/Spectre.Console/Cli/FlagValue.cs
+++ b/src/Spectre.Console/Cli/FlagValue.cs
@@ -31,7 +31,9 @@ namespace Spectre.Console.Cli
             set
             {
 #pragma warning disable CS8601 // Possible null reference assignment.
+#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
                 Value = (T)value;
+#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
 #pragma warning restore CS8601 // Possible null reference assignment.
             }
         }
diff --git a/src/Spectre.Console/Cli/Internal/Collections/MultiMap.cs b/src/Spectre.Console/Cli/Internal/Collections/MultiMap.cs
index 4a249fd..03fe449 100644
--- a/src/Spectre.Console/Cli/Internal/Collections/MultiMap.cs
+++ b/src/Spectre.Console/Cli/Internal/Collections/MultiMap.cs
@@ -165,7 +165,9 @@ namespace Spectre.Console.Cli
             if (pair.Key != null)
             {
 #pragma warning disable CS8604 // Possible null reference argument of value.
+#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
                 Add((TKey)pair.Key, (TValue)pair.Value);
+#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
 #pragma warning restore CS8604 // Possible null reference argument of value.
             }
         }
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Exclusive.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Exclusive.cs
new file mode 100644
index 0000000..10ba8e6
--- /dev/null
+++ b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Exclusive.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Spectre.Console
+{
+    /// 
+    /// Contains extension methods for .
+    /// 
+    public static partial class AnsiConsoleExtensions
+    {
+        /// 
+        /// Runs the specified function in exclusive mode.
+        /// 
+        /// The result type.
+        /// The console.
+        /// The func to run in exclusive mode.
+        /// The result of the function.
+        public static T RunExclusive(this IAnsiConsole console, Func func)
+        {
+            return console.ExclusivityMode.Run(func);
+        }
+
+        /// 
+        /// Runs the specified function in exclusive mode asynchronously.
+        /// 
+        /// The result type.
+        /// The console.
+        /// The func to run in exclusive mode.
+        /// The result of the function.
+        public static Task RunExclusive(this IAnsiConsole console, Func> func)
+        {
+            return console.ExclusivityMode.Run(func);
+        }
+    }
+}
diff --git a/src/Spectre.Console/IAnsiConsole.cs b/src/Spectre.Console/IAnsiConsole.cs
index e854fa1..8e3e7ed 100644
--- a/src/Spectre.Console/IAnsiConsole.cs
+++ b/src/Spectre.Console/IAnsiConsole.cs
@@ -23,6 +23,11 @@ namespace Spectre.Console
         /// 
         IAnsiConsoleInput Input { get; }
 
+        /// 
+        /// Gets the exclusivity mode.
+        /// 
+        IExclusivityMode ExclusivityMode { get; }
+
         /// 
         /// Gets the render pipeline.
         /// 
diff --git a/src/Spectre.Console/IExclusivityMode.cs b/src/Spectre.Console/IExclusivityMode.cs
new file mode 100644
index 0000000..fae0c41
--- /dev/null
+++ b/src/Spectre.Console/IExclusivityMode.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Spectre.Console
+{
+    /// 
+    /// Represents an exclusivity mode.
+    /// 
+    public interface IExclusivityMode
+    {
+        /// 
+        /// Runs the specified function in exclusive mode.
+        /// 
+        /// The result type.
+        /// The func to run in exclusive mode.
+        /// The result of the function.
+        T Run(Func func);
+
+        /// 
+        /// Runs the specified function in exclusive mode asynchronously.
+        /// 
+        /// The result type.
+        /// The func to run in exclusive mode.
+        /// The result of the function.
+        Task Run(Func> func);
+    }
+}
diff --git a/src/Spectre.Console/Internal/Backends/AnsiConsoleFacade.cs b/src/Spectre.Console/Internal/Backends/AnsiConsoleFacade.cs
index d01e5ae..7e41b13 100644
--- a/src/Spectre.Console/Internal/Backends/AnsiConsoleFacade.cs
+++ b/src/Spectre.Console/Internal/Backends/AnsiConsoleFacade.cs
@@ -13,9 +13,10 @@ namespace Spectre.Console
         public Profile Profile { get; }
         public IAnsiConsoleCursor Cursor => GetBackend().Cursor;
         public IAnsiConsoleInput Input { get; }
+        public IExclusivityMode ExclusivityMode { get; }
         public RenderPipeline Pipeline { get; }
 
-        public AnsiConsoleFacade(Profile profile)
+        public AnsiConsoleFacade(Profile profile, IExclusivityMode exclusivityMode)
         {
             _renderLock = new object();
             _ansiBackend = new AnsiConsoleBackend(profile);
@@ -23,6 +24,7 @@ namespace Spectre.Console
 
             Profile = profile ?? throw new ArgumentNullException(nameof(profile));
             Input = new DefaultInput(Profile);
+            ExclusivityMode = exclusivityMode ?? throw new ArgumentNullException(nameof(exclusivityMode));
             Pipeline = new RenderPipeline();
         }
 
diff --git a/src/Spectre.Console/Internal/Cell.cs b/src/Spectre.Console/Internal/Cell.cs
index c904757..5d0905c 100644
--- a/src/Spectre.Console/Internal/Cell.cs
+++ b/src/Spectre.Console/Internal/Cell.cs
@@ -1,4 +1,3 @@
-using System.Linq;
 using Spectre.Console.Rendering;
 using Wcwidth;
 
diff --git a/src/Spectre.Console/Internal/DefaultExclusivityMode.cs b/src/Spectre.Console/Internal/DefaultExclusivityMode.cs
new file mode 100644
index 0000000..3b931f8
--- /dev/null
+++ b/src/Spectre.Console/Internal/DefaultExclusivityMode.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Spectre.Console.Internal
+{
+    internal sealed class DefaultExclusivityMode : IExclusivityMode
+    {
+        private static readonly SemaphoreSlim _semaphore;
+
+        static DefaultExclusivityMode()
+        {
+            _semaphore = new SemaphoreSlim(1, 1);
+        }
+
+        public T Run(Func func)
+        {
+            // Try aquiring the exclusivity semaphore
+            if (!_semaphore.Wait(0))
+            {
+                throw new InvalidOperationException(
+                    "Trying to run one or more interactive functions concurrently. " +
+                    "Operations with dynamic displays (e.g. a prompt and a progress display) " +
+                    "cannot be running at the same time.");
+            }
+
+            try
+            {
+                return func();
+            }
+            finally
+            {
+                _semaphore.Release(1);
+            }
+        }
+
+        public async Task Run(Func> func)
+        {
+            // Try aquiring the exclusivity semaphore
+            if (!await _semaphore.WaitAsync(0).ConfigureAwait(false))
+            {
+                // TODO: Need a better message here
+                throw new InvalidOperationException(
+                    "Could not aquire the interactive semaphore");
+            }
+
+            try
+            {
+                return await func();
+            }
+            finally
+            {
+                _semaphore.Release(1);
+            }
+        }
+    }
+}
diff --git a/src/Spectre.Console/Recorder.cs b/src/Spectre.Console/Recorder.cs
index 5893b4b..4ffca3c 100644
--- a/src/Spectre.Console/Recorder.cs
+++ b/src/Spectre.Console/Recorder.cs
@@ -23,6 +23,9 @@ namespace Spectre.Console
         /// 
         public IAnsiConsoleInput Input => _console.Input;
 
+        /// 
+        public IExclusivityMode ExclusivityMode => _console.ExclusivityMode;
+
         /// 
         public RenderPipeline Pipeline => _console.Pipeline;
 
diff --git a/src/Spectre.Console/Widgets/Progress/Progress.cs b/src/Spectre.Console/Widgets/Progress/Progress.cs
index 8fc1e91..7a9f12e 100644
--- a/src/Spectre.Console/Widgets/Progress/Progress.cs
+++ b/src/Spectre.Console/Widgets/Progress/Progress.cs
@@ -118,38 +118,41 @@ namespace Spectre.Console
                 throw new ArgumentNullException(nameof(action));
             }
 
-            var renderer = CreateRenderer();
-            renderer.Started();
-
-            T result;
-
-            try
+            return await _console.RunExclusive(async () =>
             {
-                using (new RenderHookScope(_console, renderer))
-                {
-                    var context = new ProgressContext(_console, renderer);
+                var renderer = CreateRenderer();
+                renderer.Started();
 
-                    if (AutoRefresh)
+                T result;
+
+                try
+                {
+                    using (new RenderHookScope(_console, renderer))
                     {
-                        using (var thread = new ProgressRefreshThread(context, renderer.RefreshRate))
+                        var context = new ProgressContext(_console, renderer);
+
+                        if (AutoRefresh)
+                        {
+                            using (var thread = new ProgressRefreshThread(context, renderer.RefreshRate))
+                            {
+                                result = await action(context).ConfigureAwait(false);
+                            }
+                        }
+                        else
                         {
                             result = await action(context).ConfigureAwait(false);
                         }
-                    }
-                    else
-                    {
-                        result = await action(context).ConfigureAwait(false);
-                    }
 
-                    context.Refresh();
+                        context.Refresh();
+                    }
+                }
+                finally
+                {
+                    renderer.Completed(AutoClear);
                 }
-            }
-            finally
-            {
-                renderer.Completed(AutoClear);
-            }
 
-            return result;
+                return result;
+            }).ConfigureAwait(false);
         }
 
         private ProgressRenderer CreateRenderer()
diff --git a/src/Spectre.Console/Widgets/Prompt/MultiSelectionPrompt.cs b/src/Spectre.Console/Widgets/Prompt/MultiSelectionPrompt.cs
index 260c195..18696f9 100644
--- a/src/Spectre.Console/Widgets/Prompt/MultiSelectionPrompt.cs
+++ b/src/Spectre.Console/Widgets/Prompt/MultiSelectionPrompt.cs
@@ -72,6 +72,11 @@ namespace Spectre.Console
         /// 
         public List Show(IAnsiConsole console)
         {
+            if (console is null)
+            {
+                throw new ArgumentNullException(nameof(console));
+            }
+
             if (!console.Profile.Capabilities.Interactive)
             {
                 throw new NotSupportedException(
@@ -86,50 +91,53 @@ namespace Spectre.Console
                     "terminal does not support ANSI escape sequences.");
             }
 
-            var converter = Converter ?? TypeConverterHelper.ConvertToString;
-            var list = new RenderableMultiSelectionList(
-                console, Title, PageSize, Choices,
-                Selected, converter, HighlightStyle,
-                MoreChoicesText, InstructionsText);
-
-            using (new RenderHookScope(console, list))
+            return console.RunExclusive(() =>
             {
-                console.Cursor.Hide();
-                list.Redraw();
+                var converter = Converter ?? TypeConverterHelper.ConvertToString;
+                var list = new RenderableMultiSelectionList(
+                    console, Title, PageSize, Choices,
+                    Selected, converter, HighlightStyle,
+                    MoreChoicesText, InstructionsText);
 
-                while (true)
+                using (new RenderHookScope(console, list))
                 {
-                    var key = console.Input.ReadKey(true);
-                    if (key.Key == ConsoleKey.Enter)
+                    console.Cursor.Hide();
+                    list.Redraw();
+
+                    while (true)
                     {
-                        if (Required && list.Selections.Count == 0)
+                        var key = console.Input.ReadKey(true);
+                        if (key.Key == ConsoleKey.Enter)
                         {
+                            if (Required && list.Selections.Count == 0)
+                            {
+                                continue;
+                            }
+
+                            break;
+                        }
+
+                        if (key.Key == ConsoleKey.Spacebar)
+                        {
+                            list.Select();
+                            list.Redraw();
                             continue;
                         }
 
-                        break;
-                    }
-
-                    if (key.Key == ConsoleKey.Spacebar)
-                    {
-                        list.Select();
-                        list.Redraw();
-                        continue;
-                    }
-
-                    if (list.Update(key.Key))
-                    {
-                        list.Redraw();
+                        if (list.Update(key.Key))
+                        {
+                            list.Redraw();
+                        }
                     }
                 }
-            }
 
-            list.Clear();
-            console.Cursor.Show();
+                list.Clear();
+                console.Cursor.Show();
 
-            return list.Selections
-                .Select(index => Choices[index])
-                .ToList();
+                return list.Selections
+                    .Select(index => Choices[index])
+                    .ToList();
+            });
         }
     }
 }
\ No newline at end of file
diff --git a/src/Spectre.Console/Widgets/Prompt/SelectionPrompt.cs b/src/Spectre.Console/Widgets/Prompt/SelectionPrompt.cs
index 81c8f25..3c6672c 100644
--- a/src/Spectre.Console/Widgets/Prompt/SelectionPrompt.cs
+++ b/src/Spectre.Console/Widgets/Prompt/SelectionPrompt.cs
@@ -68,35 +68,38 @@ namespace Spectre.Console
                     "terminal does not support ANSI escape sequences.");
             }
 
-            var converter = Converter ?? TypeConverterHelper.ConvertToString;
-            var list = new RenderableSelectionList(
-                console, Title, PageSize, Choices,
-                converter, HighlightStyle, MoreChoicesText);
-
-            using (new RenderHookScope(console, list))
+            return console.RunExclusive(() =>
             {
-                console.Cursor.Hide();
-                list.Redraw();
+                var converter = Converter ?? TypeConverterHelper.ConvertToString;
+                var list = new RenderableSelectionList(
+                    console, Title, PageSize, Choices,
+                    converter, HighlightStyle, MoreChoicesText);
 
-                while (true)
+                using (new RenderHookScope(console, list))
                 {
-                    var key = console.Input.ReadKey(true);
-                    if (key.Key == ConsoleKey.Enter || key.Key == ConsoleKey.Spacebar)
-                    {
-                        break;
-                    }
+                    console.Cursor.Hide();
+                    list.Redraw();
 
-                    if (list.Update(key.Key))
+                    while (true)
                     {
-                        list.Redraw();
+                        var key = console.Input.ReadKey(true);
+                        if (key.Key == ConsoleKey.Enter || key.Key == ConsoleKey.Spacebar)
+                        {
+                            break;
+                        }
+
+                        if (list.Update(key.Key))
+                        {
+                            list.Redraw();
+                        }
                     }
                 }
-            }
 
-            list.Clear();
-            console.Cursor.Show();
+                list.Clear();
+                console.Cursor.Show();
 
-            return Choices[list.Index];
+                return Choices[list.Index];
+            });
         }
     }
 }
diff --git a/src/Spectre.Console/Widgets/Prompt/TextPrompt.cs b/src/Spectre.Console/Widgets/Prompt/TextPrompt.cs
index 45021bb..b570781 100644
--- a/src/Spectre.Console/Widgets/Prompt/TextPrompt.cs
+++ b/src/Spectre.Console/Widgets/Prompt/TextPrompt.cs
@@ -100,66 +100,69 @@ namespace Spectre.Console
                 throw new ArgumentNullException(nameof(console));
             }
 
-            var promptStyle = PromptStyle ?? Style.Plain;
-            var converter = Converter ?? TypeConverterHelper.ConvertToString;
-            var choices = Choices.Select(choice => converter(choice)).ToList();
-            var choiceMap = Choices.ToDictionary(choice => converter(choice), choice => choice, _comparer);
-
-            WritePrompt(console);
-
-            while (true)
+            return console.RunExclusive(() =>
             {
-                var input = console.ReadLine(promptStyle, IsSecret, choices);
+                var promptStyle = PromptStyle ?? Style.Plain;
+                var converter = Converter ?? TypeConverterHelper.ConvertToString;
+                var choices = Choices.Select(choice => converter(choice)).ToList();
+                var choiceMap = Choices.ToDictionary(choice => converter(choice), choice => choice, _comparer);
 
-                // Nothing entered?
-                if (string.IsNullOrWhiteSpace(input))
+                WritePrompt(console);
+
+                while (true)
                 {
-                    if (DefaultValue != null)
+                    var input = console.ReadLine(promptStyle, IsSecret, choices);
+
+                    // Nothing entered?
+                    if (string.IsNullOrWhiteSpace(input))
                     {
-                        console.Write(IsSecret ? "******" : converter(DefaultValue.Value), promptStyle);
-                        console.WriteLine();
-                        return DefaultValue.Value;
+                        if (DefaultValue != null)
+                        {
+                            console.Write(IsSecret ? "******" : converter(DefaultValue.Value), promptStyle);
+                            console.WriteLine();
+                            return DefaultValue.Value;
+                        }
+
+                        if (!AllowEmpty)
+                        {
+                            continue;
+                        }
                     }
 
-                    if (!AllowEmpty)
-                    {
-                        continue;
-                    }
-                }
+                    console.WriteLine();
 
-                console.WriteLine();
-
-                T? result;
-                if (Choices.Count > 0)
-                {
-                    if (choiceMap.TryGetValue(input, out result) && result != null)
+                    T? result;
+                    if (Choices.Count > 0)
                     {
-                        return result;
+                        if (choiceMap.TryGetValue(input, out result) && result != null)
+                        {
+                            return result;
+                        }
+                        else
+                        {
+                            console.MarkupLine(InvalidChoiceMessage);
+                            WritePrompt(console);
+                            continue;
+                        }
                     }
-                    else
+                    else if (!TypeConverterHelper.TryConvertFromString(input, out result) || result == null)
                     {
-                        console.MarkupLine(InvalidChoiceMessage);
+                        console.MarkupLine(ValidationErrorMessage);
                         WritePrompt(console);
                         continue;
                     }
-                }
-                else if (!TypeConverterHelper.TryConvertFromString(input, out result) || result == null)
-                {
-                    console.MarkupLine(ValidationErrorMessage);
-                    WritePrompt(console);
-                    continue;
-                }
 
-                // Run all validators
-                if (!ValidateResult(result, out var validationMessage))
-                {
-                    console.MarkupLine(validationMessage);
-                    WritePrompt(console);
-                    continue;
-                }
+                    // Run all validators
+                    if (!ValidateResult(result, out var validationMessage))
+                    {
+                        console.MarkupLine(validationMessage);
+                        WritePrompt(console);
+                        continue;
+                    }
 
-                return result;
-            }
+                    return result;
+                }
+            });
         }
 
         ///