C# C语言中的多线程控制台游标操纵竞争条件#
如果有人能给我一个正确的方向来解决我在过去两天遇到的问题,我将非常感激:我正在为VisualStudio2010控制台开发一个打字软件,需要表示时间,并且能够同时从键盘获取输入 问题是ReadLine()方法只允许我在计时器线程处于睡眠状态时进行写入,也许我可以通过委托或高级任务延续方法来解决,但我确实有点困惑,因为这些都是新概念。以下是代码(很抱歉格式太难看):C# C语言中的多线程控制台游标操纵竞争条件#,c#,multithreading,console-application,race-condition,C#,Multithreading,Console Application,Race Condition,如果有人能给我一个正确的方向来解决我在过去两天遇到的问题,我将非常感激:我正在为VisualStudio2010控制台开发一个打字软件,需要表示时间,并且能够同时从键盘获取输入 问题是ReadLine()方法只允许我在计时器线程处于睡眠状态时进行写入,也许我可以通过委托或高级任务延续方法来解决,但我确实有点困惑,因为这些都是新概念。以下是代码(很抱歉格式太难看): 使用系统; 使用System.Threading.Tasks; 使用系统线程; 命名空间类型\游戏\测试 { 类输入\和\计时器\多
使用系统;
使用System.Threading.Tasks;
使用系统线程;
命名空间类型\游戏\测试
{
类输入\和\计时器\多线程
{
公共静态无效时间读取()
{
对于(inti=1,mins=-1;i这种代码在.NET4.5.Console.ReadKey()和ReadLine()之后不再有效获取一个阻止其他线程写入控制台的锁。您需要替换它,以便不再获取该锁。这需要使用console.KeyAvailable轮询键盘。以下是console.ReadLine()的一个简单替换方法:
另外,在移动光标的另一个线程中锁定控制台锁定,以便严格分离输出。+1了解ReadKey()中的内部锁定很好
,谢谢。感谢分享您的经验,我已经按照您的指示进行了操作,但最终一切都陷入僵局,我必须在几个月后重新开始这个项目。谢谢。
using System;
using System.Threading.Tasks;
using System.Threading;
namespace Typing_Game_tests
{
class Input_and_timer_multithread
{
public static void TimerThread()
{
for (int i = 1, mins = -1; i <= 1860; i++)
{
Console.SetCursorPosition(0, 0);
if (i % 60 == 1)
{
mins++;
}
Console.WriteLine("Timer: " + mins + " minute(s) and " + i % 60 + " seconds elapsed");
Console.SetCursorPosition(0, 6);
Thread.Sleep(1000);
}
}
static string keysRead;
public static void GetInput()
{
while (Console.ReadKey(true).Key != ConsoleKey.Enter)
{
Console.SetCursorPosition(0, 6);
keysRead = Console.ReadLine();
Console.SetCursorPosition(0, 6);
}
Console.SetCursorPosition(0, 6);
Console.WriteLine(keysRead);
}
static void Main(string[] args)
{
Thread timerMain = new Thread(new ThreadStart(TimerThread));
timerMain.Start();
Task getinputMain = new Task(GetInput);
getinputMain.Start();
}
}
}
static object ConsoleLock = new object();
static string ReadString() {
var buf = new StringBuilder();
for (; ; ) {
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(31);
lock(ConsoleLock) {
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter) {
Console.WriteLine();
return buf.ToString();
}
else if (key.Key == ConsoleKey.Backspace) {
if (buf.Length > 0) {
buf.Remove(buf.Length - 1, 1);
Console.Write("\b \b");
}
}
else {
buf.Append(key.KeyChar);
Console.Write(key.KeyChar);
}
}
}
}