C# C语言中的多线程控制台游标操纵竞争条件#

C# C语言中的多线程控制台游标操纵竞争条件#,c#,multithreading,console-application,race-condition,C#,Multithreading,Console Application,Race Condition,如果有人能给我一个正确的方向来解决我在过去两天遇到的问题,我将非常感激:我正在为VisualStudio2010控制台开发一个打字软件,需要表示时间,并且能够同时从键盘获取输入 问题是ReadLine()方法只允许我在计时器线程处于睡眠状态时进行写入,也许我可以通过委托或高级任务延续方法来解决,但我确实有点困惑,因为这些都是新概念。以下是代码(很抱歉格式太难看): 使用系统; 使用System.Threading.Tasks; 使用系统线程; 命名空间类型\游戏\测试 { 类输入\和\计时器\多

如果有人能给我一个正确的方向来解决我在过去两天遇到的问题,我将非常感激:我正在为VisualStudio2010控制台开发一个打字软件,需要表示时间,并且能够同时从键盘获取输入

问题是ReadLine()方法只允许我在计时器线程处于睡眠状态时进行写入,也许我可以通过委托或高级任务延续方法来解决,但我确实有点困惑,因为这些都是新概念。以下是代码(很抱歉格式太难看):

使用系统;
使用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);
            }
        }
    }
}