I am learning about socket messaging. I interrupted Console.ReadKey() in a while loop and a lot of the calls ended up incomplete. I am trying to find a way to remove the incomplete calls without the user typing it all out.
I have seen
while(Console.KeyAvailable){Console.ReadKey(true);}
but I have the opposite problem too many calls not enough Key strokes.
How to add a Timeout to Console.ReadLine()? This question got me to where I am now, but it doesn't solve my current problem.
using System;
using System.Threading;
class Program
{
static void Main(string[] args)
{
DontLockOnCharGet bug = new DontLockOnCharGet();
bug.Setup();
}
}
public class DontLockOnCharGet
{
public void Setup()
{
while (true) { DontLockCharGet(); }
}
public void DontLockCharGet()
{
while (true)
{
// used to interrupt the Console.ReadKey() function
AutoResetEvent getInput = new AutoResetEvent(false);
AutoResetEvent gotInput = new AutoResetEvent(false);
// Console.ReadKey() assigns to input
char input = ' ';
//Lambda used to get rid of extra class
Thread tom = new Thread(() =>
{
getInput.WaitOne(); // Waits for getInput.Set()
//The problem with this is the read keys stacking up
// causing the need for a lot of keystrokes
input = Console.ReadKey().KeyChar;
gotInput.Set();
})
{
IsBackground = true
};
// Starts Lambda function
tom.Start();
// Allows thread to pass WaitOne() in Lambda
getInput.Set();
// Gives some milliseconds for before stopping Lambda exe
gotInput.WaitOne(2000);
if (input == 'S' || input == 's')
{
break;
}
// thinking I would put the solution here
//...
}
//Do stuff if input is s || S
Console.Write("end: ");
}
}
I expect to be able to press 's' || 'S' and then type out a message, but depending on how long I have been waiting I may have to hold 's' for a long time.
The solution I happened across because of the first comment.
using System;
using System.Threading;
/// <summary>
/// Problem fixed I don't know why
/// Probably not making a new function for each call
/// </summary>
class Program
{
static void Main(string[] args)
{
DontLockOnCharGet bug = new DontLockOnCharGet();
bug.Setup();
}
}
public class DontLockOnCharGet
{
public void Setup()
{
while (true) { DontLockCharGet(); }
}
public void DontLockCharGet()
{
while (true)
{
//Specifies time to wait for input
char i = Reader.ReadKey(1000);
if (i == 's' || i == 'S')
{
//Do stuff if input is s || S
break;
}
Console.Write(i);
}
// Do stuff
Console.Write("end: ");
}
}
class Reader
{
private static Thread inputThread;
private static AutoResetEvent getInput, gotInput;
private static char input;
static Reader()
{
//Setup once
getInput = new AutoResetEvent(false);
gotInput = new AutoResetEvent(false);
//inputThread = new Thread(reader);
//inputThread.IsBackground = true;
//inputThread.Start();
}
private static void reader()
{
//waits for .Set()
getInput.WaitOne();
input = '\0';
input = Console.ReadKey().KeyChar;
//Marks if input is gotten
gotInput.Set();
}
// omit the parameter to read a line without a timeout
public static char ReadKey(int timeOutMillisecs = Timeout.Infinite)
{
//Setup and start read thread
inputThread = new Thread(reader)
{
IsBackground = true
};
inputThread.Start();
//Allows thread to continue in reader()
getInput.Set();
//Wait for input or back out befor it is given
bool success = gotInput.WaitOne(timeOutMillisecs);
return input;
}
}
This version of code works as expected: Type 'S' and it auto-completes to "Send: "
The problem is in the new Thread(()=> { ... });
This is creating a new function not just a new function call. The function being created should be moved into a separate function like this
private void ReadKey(){
// Waits for getInput.Set()
getInput.WaitOne();
//The problem with this is the read keys stacking up
// causing the need for a lot of keystrokes
input = Console.ReadKey().KeyChar;
gotInput.Set();
}
inside the class.
Make these
AutoResetEvent getInput, gotInput;
char input;
class variables and initialize them inside Setup(){...}
Finally call Thread tom = new Thread(ReadKey);
where the new function is currently being made.
Note: This answer is not for best practice use, but will get a prototype to work.