Here is another idea, it's written in C# and usable for both C# and VB.NET. Create a new C# Class project and add the following class.
using System;
using System.Threading.Tasks;
using static System.Console;
namespace ConsoleHelpers
{
public static class ConsoleKeysHelper
{
public static void WaitReadLine(string message = "Press any key to terminate.")
{
WriteSectionBold(message,false);
Console.ReadLine();
}
public static void WriteSectionBold(string message, bool line = true)
{
var originalForeColor = ForegroundColor;
ForegroundColor = ConsoleColor.White;
WriteLine(message);
ForegroundColor = originalForeColor;
if (line)
{
WriteLine(new string('-', 100));
}
}
/// <summary>
/// Provides an enhanced Console.ReadLine with a time out.
/// </summary>
/// <param name="timeout">Timeout</param>
/// <param name="message">Optional text to display</param>
/// <returns>Input from a Task or if no input an empty string</returns>
/// <remarks>
/// Example, wait for two seconds and a half
/// ConsoleReadLineWithTimeout(TimeSpan.FromSeconds(2.5))
///
/// Example, use default, wait for one second
/// ConsoleReadLineWithTimeout(TimeSpan.FromSeconds())
/// </remarks>
public static string ReadLineWithTimeout(TimeSpan? timeout = null, string message = "")
{
if (!string.IsNullOrWhiteSpace(message))
{
WriteSectionBold(message, false);
}
TimeSpan timeSpan = timeout ?? TimeSpan.FromSeconds(1);
var task = Task.Factory.StartNew(Console.ReadLine);
var result = (Task.WaitAny(new Task[] { task }, timeSpan) == 0) ? task.Result : string.Empty;
return result;
}
/// <summary>
/// Read line with timeout and optional message
/// </summary>
/// <param name="seconds"></param>
/// <param name="message"></param>
/// <returns></returns>
public static string ReadLineWithTimeout(int seconds, string message = "")
{
if (!string.IsNullOrWhiteSpace(message))
{
WriteSectionBold(message, false);
}
TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
var task = Task.Factory.StartNew(Console.ReadLine);
var result = (Task.WaitAny(new Task[] { task }, timeSpan) == 0) ? task.Result : string.Empty;
return result;
}
public static string ReadLineFiveSeconds(string message = "") => ReadLineWithTimeout(5, message);
public static string PauseFiveSeconds(string message = "") => ReadLineWithTimeout(5, message);
public static string ReadLineTenSeconds(string message = "") => ReadLineWithTimeout(10, message);
public static string PauseTenSeconds(string message = "") => ReadLineWithTimeout(10, message);
}
}
Add a reference to a VB.NET for the above to a Console project and use
Module Program
Sub Main(args As String())
Dim value = ReadLineFiveSeconds("Please enter your name within the next 5 seconds.")
Console.WriteLine(value)
End Sub
End Module
For C#
class Program
{
static void Main(string[] args)
{
var value = ReadLineFiveSeconds( "Please enter your name within the next 5 seconds.");
Console.WriteLine(value);
}
}
Both support
static void Main(string[] args)
{
var value = ReadLineWithTimeout(5, "Please enter your name within the next 5 seconds.");
Console.WriteLine(value);
}
I have full source code for the class project with more goodies.
Note if this was C# we could also have a async Main and use
Console.WriteLine("Enter some text");
var task = Task.Factory.StartNew(Console.ReadLine);
var completedTask = await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(5)));
var result = ReferenceEquals(task, completedTask) ? task.Result : string.Empty;
Console.WriteLine(result);