c# 不完整的 Console.ReadKey() 调用我不希望用户完成
c# incomplete Console.ReadKey() calls I don't want the user to complete
我正在学习套接字消息传递。我在一个 while 循环中打断了 Console.ReadKey() 并且很多调用都没有完成。我正在尝试找到一种方法来删除不完整的调用,而无需用户将其全部输入。
我看过
while(Console.KeyAvailable){Console.ReadKey(true);}
但我有相反的问题,调用太多,击键次数不够。
How to add a Timeout to Console.ReadLine()?
这个问题把我带到了现在的位置,但它并没有解决我当前的问题。
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: ");
}
}
我希望能够按下 's' || 'S' 然后输入一条消息,但根据我等待的时间长短,我可能需要按住 's' 很长时间。
我因为第一条评论而遇到的解决方案。
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 = '[=13=]';
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;
}
}
此版本的代码按预期工作:
输入 'S' 并自动完成 "Send: "
问题出在new Thread(()=> { ... });
这是在创建一个新函数,而不仅仅是一个新函数调用。正在创建的函数应该像这样移动到一个单独的函数中
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();
}
里面 class.
做这些
AutoResetEvent getInput, gotInput;
char input;
class 变量并在 Setup(){...}
中初始化它们
最后调用Thread tom = new Thread(ReadKey);
当前正在制作新功能的地方。
注意:此答案不适用于最佳实践,但会得到一个原型。
我正在学习套接字消息传递。我在一个 while 循环中打断了 Console.ReadKey() 并且很多调用都没有完成。我正在尝试找到一种方法来删除不完整的调用,而无需用户将其全部输入。
我看过
while(Console.KeyAvailable){Console.ReadKey(true);}
但我有相反的问题,调用太多,击键次数不够。
How to add a Timeout to Console.ReadLine()? 这个问题把我带到了现在的位置,但它并没有解决我当前的问题。
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: ");
}
}
我希望能够按下 's' || 'S' 然后输入一条消息,但根据我等待的时间长短,我可能需要按住 's' 很长时间。
我因为第一条评论而遇到的解决方案。
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 = '[=13=]';
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;
}
}
此版本的代码按预期工作: 输入 'S' 并自动完成 "Send: "
问题出在new Thread(()=> { ... });
这是在创建一个新函数,而不仅仅是一个新函数调用。正在创建的函数应该像这样移动到一个单独的函数中
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();
}
里面 class.
做这些
AutoResetEvent getInput, gotInput;
char input;
class 变量并在 Setup(){...}
最后调用Thread tom = new Thread(ReadKey);
当前正在制作新功能的地方。
注意:此答案不适用于最佳实践,但会得到一个原型。