This is the solution I came up with to pause/resume an active thread inside a console…
It requires a second thread for input, which the main loop reacts too. But my ignorance of C# makes me wonder if there is a simpler solution? Perhaps one that can be done with the main thread alone?
Essentially, I am testing several things that will iterate at the defined FPS, and I want to be able to pause and resume the iteration via keyboard input. Any feedback is appreciated.
class TestLoops
{
int targetMainFPS = 5;
int targetInputFPS = 3;
bool CONTINUE = true;
Thread testLoop, testLoop2;
ConsoleKeyInfo cki;
ManualResetEvent resetThread = new ManualResetEvent(true); //How to correctly pause threads in C#.
public void Resume() { resetThread.Set(); }
public void Pause() { resetThread.Reset(); }
public TestLoops()
{
//_start = DateTime.Now.Ticks;
Console.Write("CreatingLoop...");
this.testLoop = new Thread(MainLoop);
this.testLoop.Start();
this.testLoop2 = new Thread(InputLoop);
this.testLoop2.Start();
}
void MainLoop()
{
long _current = 0;
long _last = 0;
Console.Write("MainLoopStarted ");
while(CONTINUE)
{
resetThread.WaitOne();
_current = DateTime.Now.Ticks / 1000;
if(_current > _last + (1000 / targetMainFPS) )
{
_last = _current;
//Do something...
Console.Write(".");
}
else
{
System.Threading.Thread.Sleep(10);
}
}
}
void InputLoop()
{
long _current = 0;
long _last = 0;
Console.Write("InputLoopStarted ");
while(CONTINUE)
{
_current = DateTime.Now.Ticks / 1000;
if(_current > _last + (1000 / targetInputFPS))
{
_last = _current;
//Manage keyboard Input
this.cki = Console.ReadKey(true);
//Console.Write(":");
if(this.cki.Key == ConsoleKey.Q)
{
//MessageBox.Show("'Q' was pressed.");
CONTINUE = false;
}
if(this.cki.Key == ConsoleKey.P)
{
this.Pause();
}
if(this.cki.Key == ConsoleKey.R)
{
this.Resume();
}
}
else
{
System.Threading.Thread.Sleep(10);
}
}
}
public static void Main(string[] args)
{
TestLoops test = new TestLoops();
}
}
You can simplify it drastically by using the non-blocking
Console.KeyAvailablecheck. That way, you can execute all your code from the main thread:Edit: Replying to comment.
Be careful. The code below blocks due to the
Console.ReadKeycall, not due to thewhileloop. Thewhileloop is there only so that, if the user enters a character other thanR, the program would discard it and wait for another character to be entered.If you wanted to block until any character is pressed, you would simply use: