I'm attempting to work with the Console.ReadKey() function in order to intercept the user's keystrokes and rebuild what they are typing on the screen (as I'll need to clear the screen often, move the cursor often, and this seemed like the most full-proof method of making sure what they typed didn't vanish or appear at random points all over the screen.
My question is: Has anyone else ever experienced a 1 character "lag", for lack of a better term, when doing something similar? Say I want to type the word "This". When I press "T", nothing shows up, no matter how long I wait. When I press "h", the "T" appears. "i", the "h" appears. The letter I type will not appear until I hit another key, even if that key is the space bar. Does anyone have any suggestions for what I am doing wrong? I'm sure it has to do with how I am using Console.Readkey, I just don't see what alternative would work. I have attached a small and simple example of this below.
Thank you!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
private static string userInput = "";
static ConsoleKeyInfo inf;
static StringBuilder input = new StringBuilder();
static void Main(string[] args)
{
Thread tickThread = new Thread(new ThreadStart(DrawScreen));
Thread userThread = new Thread(new ThreadStart(UserEventHandler));
tickThread.Start();
Thread.Sleep(1);
userThread.Start();
Thread.Sleep(20000);
tickThread.Abort();
userThread.Abort();
}
private static void DrawScreen()
{
while (true)
{
Console.Clear();
Console.SetCursorPosition(0, 0);
Console.Write("> " + userInput);
Thread.Sleep(300);
}
}
private static void UserEventHandler()
{
inf = Console.ReadKey(true);
while (true)
{
if (inf.Key != ConsoleKey.Enter)
input.Append(inf.KeyChar);
else
{
input = new StringBuilder();
userInput = "";
}
inf = Console.ReadKey(true);
userInput = input.ToString();
}
}
}
}
It is because you have 2 times Console.ReadKey()
If you change your code into this
private static void UserEventHandler()
{
while (true)
{
inf = Console.ReadKey(true);
if (inf.Key != ConsoleKey.Enter)
input.Append(inf.KeyChar);
else
{
input = new StringBuilder();
userInput = "";
}
userInput = input.ToString();
}
}
It does not lag. the second Console.ReadKey() is blocking in your code. I did not check if you need the parameter true to the readkey, that's for you to find out
Related
I am required to write a program that prints out numbers until I write in the console window a simple string "stop". The numbers are supposed to go on infinitely until the condition is met.
I tried:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000000000;)
{
Console.WriteLine(i);
string a = Console.ReadLine();
if (a == "stop")
{
break;
}
i++;
}
}
}
}
But, there is a delay waiting for my input every time, it's not constant.
You are asking for a non blocking console read. THats not simple.
One way is to peek to see if a key is available to read
int number = 0;
while (true)
{
Console.WriteLine(number);
number++;
if (Console.KeyAvailable)
{
var s = Console.ReadLine();
if (s == "stop")
break;
}
}
I have created a game that gives a player 5 chances to play after which I would like to ask the player if they would like to play again or quit. I have seen it done in Python, but I do not know python. My code works perfectly fine, but I would like to add these two additional functions
How can I achieve these functionality in C#?
For reference this is what my code main class code looks like.
namespace NumBaseBall
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("\t\t\t*************************************");
Console.WriteLine("\t\t\t* Let's Have Some Fun *");
Console.WriteLine("\t\t\t* Welcome To The *");
Console.WriteLine("\t\t\t* Number Baseball Game *");
Console.WriteLine("\t\t\t*************************************\n");
GameResults gameresults = new GameResults();
for (int trysCounter = 1; trysCounter <= 5; trysCounter++)
{
gameresults.Strikes = 0;
Random r = new Random();
var myRange = Enumerable.Range(1, 9);
var computerNumbers = myRange.OrderBy(i => r.Next()).Take(3).ToList();
Console.WriteLine("The Game's Three Random Integers Are: (Hidden from user)");
foreach (int integer in computerNumbers)
{
Console.WriteLine("{0}", integer);
}
List<int> playerNumbers = new List<int>();
Console.WriteLine("Please Enter Three Unique Single Digit Integers and Press ENTER after each:");
for (int i = 0; i < 3; i++)
{
Console.Write("");
int number = Convert.ToInt32(Console.ReadLine());
playerNumbers.Add(number);
}
gameresults.StrikesOrBalls(computerNumbers,playerNumbers);
Console.WriteLine("---> Computer's Numbers = {0}{1}{2}", computerNumbers[0], computerNumbers[1], computerNumbers[2]);
Console.WriteLine("---> Player's Numbers = {0}{1}{2}", playerNumbers[0], playerNumbers[1], playerNumbers[2]);
Console.WriteLine("---> Game Results = {0} STRIKES & {1} BALLS\n", gameresults.Strikes, gameresults.Balls);
Console.WriteLine("You have played this games {0} times\n", trysCounter);
gameresults.TotalStrikes = gameresults.TotalStrikes + gameresults.Strikes;
Console.WriteLine("STRIKES = {0} ", gameresults.TotalStrikes);
if (gameresults.TotalStrikes >= 3)
{
gameresults.Wins++;
Console.WriteLine("YOU ARE A WINNER!!!");
break;
}
}
if (gameresults.TotalStrikes <3)
Console.WriteLine("YOU LOSE :( PLEASE TRY AGAIN!");
}
}
}
Insert your code inside an loop which checks if the user wants to continue:
while(true) // Continue the game untill the user does want to anymore...
{
// Your original code or routine.
while(true) // Continue asking until a correct answer is given.
{
Console.Write("Do you want to play again [Y/N]?");
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
break; // Exit the inner while-loop and continue in the outer while loop.
if (answer == "N")
return; // Exit the Main-method.
}
}
But perhaps it would be better to split one big routine up into seperate routines.
Lets rename your Main-method to PlayTheGame.
Split up my routines into:
static public bool PlayAgain()
{
while(true) // Continue asking until a correct answer is given.
{
Console.Write("Do you want to play again [Y/N]?");
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
return true;
if (answer == "N")
return false;
}
}
And now the Main-method can be:
static void Main(string[] args)
{
do
{
PlayTheGame();
}
while(PlayAgain());
}
You'de have to move some local variables to the class as static fields. Or you could make an instance of a Game class, but I think that is one step to far right now.
There are two ways you could accomplish this:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.kill%28v=vs.110%29.aspx
System.Diagnostics.Process.GetCurrentProcess().Kill();
Or
https://msdn.microsoft.com/en-us/library/system.environment.exit(v=vs.110).aspx
int exitCode =1;
System.Environment.Exit(exitCode);
Environment.Exit is the preferred way to exit your program since the Kill command "causes an abnormal process termination and should be used only when necessary."[msdn]
First, take the suggestion of moving the code for the actual game playing into a separate function. It will clean things up a lot.
Something like
private static bool PlayGame()
{
// Win branch returns true.
// Loss branch returns false.
}
This then lets you greatly simplify the Main function allowing it to only handle the menu functionality.
For the actual menu functionality, I tend to prefer do/while loops. You have a bit of an extra stipulation that you only ask after 5 plays, but that's easy enough to deal with.
static void Main(string[] args)
{
int playCount = 0;
string answer = "Y";
bool winner;
do
{
if(playCount < 5)
{
playCount++;
}
else
{
do
{
Console.Write("Play again? (Y/N): ");
answer = Console.ReadLine().ToUpper();
} while(answer != "Y" && answer != "N");
}
winner = PlayGame();
} while(!winner && answer == "Y");
Console.WriteLine("Thanks for playing!");
}
You could simplify it a bit by moving the test for 5 games into the if conditional with the use of an increment operator. The only issue is if someone plays your game a billion or so times, things might get weird.
static void Main(string[] args)
{
int playCount = 0;
string answer = "Y";
bool winner;
do
{
if(playCount++ > 3)
{
do
{
Console.Write("Play again? (Y/N): ");
answer = Console.ReadLine().ToUpper();
} while(answer != "Y" && answer != "N");
}
winner = PlayGame();
} while(!winner && answer == "Y");
Console.WriteLine("Thanks for playing!");
}
Edit: Changed things a bit as it looks like in your original code the game ends after the person wins the game.
Per your question in your comment below, you could make a static instance of your GameResults class in your Program class. Your code would end up looking something like the following
class Program
{
private static GameResults results = new GameResults();
public static void Main(string[] args)
{
// Code
}
private static bool PlayGame()
{
// Code
}
}
In PlayGame you would just use the static results object instead of creating a new one every time PlayGame is called.
I'm trying to make a test to see if someone has certain skills.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class timerup
{
public bool timeup = false;
}
class Program
{
public static void timer()
{
for (int i = 1; i < 3; i++)
{
System.Threading.Thread.Sleep(1000);
if (i == 5)
{
object a;
a = true;
a = new timerup();
timerup ClassRef;
ClassRef = (timerup)a;
ClassRef.timeup = true;
}
}
}
static void Main(string[] args)
{
Console.Title = "The Secret Agent Test";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Welcome, agent. This is the test to see if\nyou are good enough to be a full member of the OT Secret Agency.");
Console.WriteLine("Do you want to continue? [Y/N]");
string cont = Console.ReadLine();
if (cont == "y" || cont =="Y")
{
Console.Clear();
Console.WriteLine("Let's continue the test.");
Console.WriteLine("Crack the password:");
Console.WriteLine("Username: IDIOT_NOOB1337\nPROFILE: Likes memes such as doge.\nIs an elitist (Over the things he likes)\nOnly uses the word idiot as an insult");
Console.WriteLine("Password:");
string pass1 = Console.ReadLine();
if (pass1 == "AnyoneWhoDoesn'tLikeDogeIsAnIdiot" || pass1 == "anyonewhodoesn'tlikedogeisanidiot")
{
Console.WriteLine("Account accessed.");
Console.WriteLine("Stage 1 Complete.");
Console.WriteLine("Loading next level...");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Level 2 loaded.");
System.Threading.Thread.Sleep(1000);
Console.Clear();
Console.WriteLine("Nice. You certainly have skill. But this test.... determines speed of mind.");
System.Threading.Thread.Sleep(2500);
Console.Clear();
Console.WriteLine("You only have two seconds to answer the next question. Press any key when ready.");
Console.ReadKey();
Console.Clear();
Console.WriteLine("What is 12x12?!"); // QUESTION
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(timer)); // SUCH COMPLEX CODE FOR A TIMER... WTF.
string product = Console.ReadLine();
object b;
b = true;
b = new timerup();
timerup ClassRef;
ClassRef = (timerup)b;
bool timerthing = ClassRef.timeup;
if (product != "144" || timerthing == true)
{
Console.WriteLine("Sorry, you are incorrect. Restart the test again.");
System.Threading.Thread.Sleep(2000);
Console.Clear();
System.Environment.Exit(-1);
}
else
{
Console.WriteLine("Impressive. Your mind is fast, too. Well, be prepared for the next test. Pressure.");
}
}
}
}
}
}
The thread does not execute; I suspect it is because of the string product = Console.ReadLine(); bit. The second question of this quiz was 12x12, and you have 2 seconds to answer, except the thread that counted the two seconds wasn't executed... Why...? And if you know, how would I fix it?
You only created a thread. You should also start it.
System.Threading.Thread t = new System.Threading.Thread(timer);
t.Start();
Just wrote this down as an example of how you can check for how long time has passed without using a thread.
bool isInTime = false;
var start = DateTime.Now;
Console.WriteLine("answer this in 5 seconds, what is 2x2");
var answer = Console.ReadLine();
if ((DateTime.Now - start).TotalSeconds <= 5)
isInTime = true;
if (isInTime && answer == "4")
Console.WriteLine("Good job you are now an agent");
else
Console.WriteLine("To slow and too dumb");
Console.ReadKey();
Stopwatch is another alternative: http://www.dotnetperls.com/stopwatch
If you really want threads (which are overkill for this problem) there are some good examples here: https://msdn.microsoft.com/en-us/library/ts553s52(v=vs.110).aspx
The two answers are on the spot, so let me just add how you can create a timer that's not as convoluted :)
var timeIsUp = false;
var timer = new Timer(_ => { timeIsUp = true; }, null, 5000, Timeout.Infinite);
But in general, #JensB is absolutely right - using multi-threading should be the last option. It's very hard to handle multi-threading properly, so avoiding it is a pretty decent strategy. The Timer example I've shown is also multi-threaded - the callback on the timer will occur on a different thread. This introduces synchronization issues, but they shouldn't be too painful for a simple case like this. To improve upon this, you'd at least want to ensure the local is updated safely:
var syncObject = new object();
var timeIsUp = false;
var timer = new Timer(_ => { lock (syncObject) { timeIsUp = true; } }, null, 5000,
Timeout.Infinite);
var answer = Console.ReadLine();
lock (syncObject)
{
if (timeIsUp) ...
}
Finally, using Thread manually is completely unnecessary nowadays. It's much easier to use Tasks for concurrency and multi-threading. For example:
var timerTask = Task.Delay(5000);
var answer = Console.ReadLine();
if (timerTask.IsCompleted) Console.WriteLine("Too late");
The best option IMO would be to use proper asynchronous APIs - sadly, the .NET Console class doesn't have those. As silly as it is, it seems that this is a pretty decent option:
void Main()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(2));
var task = Task.Run(() => ReadLineFromConsole(cts.Token));
task.Wait(cts.Token);
if (task.IsCanceled)
{
Console.WriteLine("Too slow!");
return;
}
var result = task.Result;
if (result != "144")
{
Console.WriteLine("Wrong!");
return;
}
// Continue
}
public string ReadLineFromConsole(CancellationToken token)
{
var buffer = new StringBuilder();
int ch;
while (!token.IsCancellationRequested)
{
Console.In.Peek();
token.ThrowIfCancellationRequested();
ch = Console.In.Read();
if (ch == -1) return buffer.Length > 0 ? buffer.ToString() : null;
if (ch == '\r' || ch == '\n')
{
if (ch == '\r' && Console.In.Peek() == '\n') Console.In.Read();
return buffer.ToString();
}
buffer.Append((char)ch);
}
token.ThrowIfCancellationRequested();
// Shouldn't be reached, but the compiler doesn't know that.
return null;
}
The interesting point about this approach is that I can exit the application (and abort the input) even if the user doesn't press enter. It also allows you to tie together complex work flows using await, although that's slightly tricky in a console application.
The helper method ReadLineFromConsole actually works the same as the usual ReadLine method, however, it also checks for cancellation, and to prevent it from "stealing" data from later ReadLine calls, it will Peek first. This doesn't make it thread-safe - you still shouldn't using multiple readlines at the same time from different threads. But it does mean that we can ignore the output when it finally comes. Bear in mind that the thread will be waiting all this time until a console input comes - do not use this to launch multiple simultaneous requests without ensuring there's some input on the way eventually (e.g. using the usual Console.ReadLine in between the ReadLineFromConsole calls etc.).
Some refactoring to your code and solution to your problem :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication2
{
class Program
{
static void WriteText(params string[] lines) { WriteText(0, lines); }
static void WriteText(double delaySecs, params string[] lines)
{
for (int i = 0; i < lines.Length; i++) Console.WriteLine(lines[i]);
if (delaySecs > 0) Thread.Sleep(TimeSpan.FromSeconds(delaySecs));
}
static void Main(string[] args)
{
Console.Title = "The Secret Agent Test";
Console.ForegroundColor = ConsoleColor.Green;
WriteText("Welcome, agent. This is the test to see if\nyou are good enough to be a full member of the OT Secret Agency.", "Do you want to continue? [Y/N]");
var readk = Console.ReadKey();
if (readk.Key == ConsoleKey.Y || readk.Key == ConsoleKey.N)
{
Console.Clear();
WriteText("Let's continue the test.\n", "Crack the password:\n", "Username: IDIOT_NOOB1337\nPROFILE: Likes memes such as doge.",
"Is an elitist (Over the things he likes)", "Only uses the word idiot as an insult", "Password:");
string pass1 = Console.ReadLine();
if (pass1 != "AnyoneWhoDoesn'tLikeDogeIsAnIdiot" && pass1 != "anyonewhodoesn'tlikedogeisanidiot") return;
WriteText(2, "Account accessed.", "Stage 1 Complete.", "Loading next level...");
WriteText(1, "Level 2 loaded.");
Console.Clear();
WriteText(2.5, "Nice. You certainly have skill. But this test.... determines speed of mind.");
Console.Clear();
Console.WriteLine("You only have two seconds to answer the next question. Press any key when ready.");
Console.ReadKey();
Console.Clear();
Console.WriteLine("What is 12x12?!"); // QUESTION
int allowedTime = 2 * 1000; // time allowed
new Thread(() =>
{
Stopwatch s = new Stopwatch();
s.Start();
while (s.ElapsedMilliseconds < allowedTime) { }
WriteText(2, "Sorry, you're too late. Restart the test again.");
Console.Clear();
Environment.Exit(-1);
}).Start();
string product = Console.ReadLine();
if (product == "144") Console.WriteLine("Impressive. Your mind is fast, too. Well, be prepared for the next test. Pressure.");
WriteText(2, "Sorry, you are incorrect. Restart the test again.");
Console.Clear();
}
}
}
}
I'm having issues with with making a program.
I need to make it so it checks whether a text file exists or not, if it exists it displays the contents, if not it prompts the user to enter 5 names, these names are stored into an array are then sent to the text document. I've already tried to do it but I'm getting an error.
Note:
I need to do the names in an array.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;
namespace Array
{
class Program
{
public static string line;
public const string file = #"D:\information.txt";
public static string names = #"D:\names.txt";
public static StreamReader myFile = new StreamReader(names);
public static string[] namesArray = new string[4];
public static bool checkFileExists(string names)
{
bool b = false;
if (File.Exists(names))
{
b = true;
}
return b;
}
static void reset() //void used to reset the program
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("\nIf there is an error, press Enter to restart");
Console.ForegroundColor = ConsoleColor.White; //changes the text colour of the next line of code to white, better visuals
Console.ReadLine(); //the readkey used to read for any keys being pressed for restarting
Console.Clear(); //clears the console and resets it back to normal
}
static void toFile()
{
Console.ForegroundColor = ConsoleColor.White;
string[] namesArray = new string[5];
Random RandString = new Random();
StreamWriter info = new StreamWriter(file);
for (int x = 0; x < namesArray.Length; x++)
{
Console.Write("Enter a name of class member: {0}", namesArray[x]);
namesArray[x] = Console.ReadLine();
}
for (int x = 0; x < namesArray.Length; x++)
{
info.WriteLine("{0}", namesArray[x]);
}
info.Close();
}
static void Main(string[] args)
{
Console.Title = "Class names to array";
try
{
if (checkFileExists(names))
{
Console.WriteLine("file exists, the contents of the file is: ");
while (myFile1.EndOfStream == false)
{
line = myFile1.ReadLine();
Console.WriteLine(line);
}
Console.ReadLine();
}
else
{
toFile();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
The error I'm getting is 'The type initializer for 'Array.Program' threw an exception' and it just closes down.
I've also been told by a friend that my code is really messy, I'm not sure what I need to do to make it better but any help is appreciated.
As #cdhowie said, you will find the details in InnerException. I did notice that your code was a little bit strung out, and admittedly messy, so I decided to write a little sample that does what you want it to in way fewer lines. Many times when doing simple file operations, you can avoid using StreamReader or StreamWriter and instead just use the File class.
Here is the code sample:
using System;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string file = #"D:\information.txt";
if (File.Exists(file))
foreach(var s in File.ReadAllLines(file))
Console.WriteLine(s);
else
{
string[] src = new string[5];
Console.WriteLine("Please enter 5 names:");
for (int i = 0; i < 5; i++)
src[i] = Console.ReadLine();
File.Create(file).Close();
File.WriteAllLines(file, src)
}
}
}
}
Check the details of the "inner exception" in a debugger. You should see that the problem is this line:
public static StreamReader myFile = new StreamReader(names);
This is the only line that could be causing this problem, and likely occurs because the filename contained by the names field doesn't exist, or you don't have access to it (permissions or sharing violation, for example). Correct the problem indicated by the inner exception to make the exception stop happening.
Note that if you did this assignment in the Main() method that the real error would not be masked by the TypeInitializationException, which is thrown whenever a static constructor throws an exception.
i just need to be able to loop a console app. what i mean by that is:
program start:
display text
get input
do calculation
display result
display text
get input.
REPEAT PROCESS INFINATE NUMBER OF TIMES UNTIL THE USER EXITS THE APPLICATION.
program end.
i hope that made sense. can anyone please explain how i would go about doing this? thank you :)
Console.WriteLine("bla bla - enter xx to exit");
string line;
while((line = Console.ReadLine()) != "xx")
{
string result = DoSomethingWithThis(line);
Console.WriteLine(result);
}
while(true) {
DisplayText();
GetInput();
DoCalculation();
DisplayResult();
DisplayText();
GetInput();
}
The user can stop the program at any point with CTRL-C.
Is this what you meant?
You could wrap the whole body of your Main method in program.cs in a while loop with a condition that will always be satisfied.
E.g (in pseudo-code)
While (true)
{
Body
}
Kindness,
Dan
Use a While loop
bool userWantsToExit = false;
get input
while(!userWantsToExit)
{
do calc;
display results;
display text;
get input;
if (input == "exit")
userWantsToExit = true;
}
program end;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace InputLoop
{
class Program
{
static long PrintFPSEveryXMilliseconds = 5000;
static double LimitFPSTo = 10.0;
static void Main(string[] args)
{
ConsoleKeyInfo Key = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false);
long TotalFrameCount = 0;
long FrameCount = 0;
double LimitFrameTime = 1000.0 / LimitFPSTo;
do
{
Stopwatch FPSTimer = Stopwatch.StartNew();
while (!Console.KeyAvailable)
{
//Start of Tick
Stopwatch SW = Stopwatch.StartNew();
//The Actual Tick
Tick();
//End of Tick
SW.Stop();
++TotalFrameCount;
++FrameCount;
if (FPSTimer.ElapsedMilliseconds > PrintFPSEveryXMilliseconds)
{
FrameCount = PrintFPS(FrameCount, FPSTimer);
}
if (SW.Elapsed.TotalMilliseconds < LimitFrameTime)
{
Thread.Sleep(Convert.ToInt32(LimitFrameTime - SW.Elapsed.TotalMilliseconds));
}
else
{
Thread.Yield();
}
}
//Print out and reset current FPS
FrameCount = PrintFPS(FrameCount, FPSTimer);
//Read input
Key = Console.ReadKey();
//Process input
ProcessInput(Key);
} while (Key.Key != ConsoleKey.Escape);
}
private static long PrintFPS(long FrameCount, Stopwatch FPSTimer)
{
FPSTimer.Stop();
Console.WriteLine("FPS: {0}", FrameCount / FPSTimer.Elapsed.TotalSeconds);
//Reset frame count and timer
FrameCount = 0;
FPSTimer.Reset();
FPSTimer.Start();
return FrameCount;
}
public static void Tick()
{
Console.Write(".");
}
public static void ProcessInput(ConsoleKeyInfo Key)
{
Console.WriteLine("Pressed {0} Key", Key.KeyChar.ToString());
}
}
}
You can just put a loop around whatever you're doing in your program.