C#同时控制台输入输出?我正在编写一个服务器应用程序,我希望它是基于控制台的。我需要用户能够输入不同的命令,但同时可能会在用户写入时向控制台输出一些内容。这弄乱了缓冲区。有什么干净的方法可以做到这一点吗?谢谢。我开始编写一个测试程序来展示如何将控制台分为输出区域和输入区域,输出区域随着输出区域的扩展而获得更多输出。它还不完美,但你可以将它展开成你正在寻找的答案:staticintoutCol,outRow,outHeight=10;staticvoidMain(string[]args){boolquit=false;System.DateTimedt=DateTime.Now;做{if(Console.KeyAvailable){if(Console.ReadKey(false).Key==ConsoleKey.Escape)quit=true;}System.Threading.Thread.Sleep(0);如果(DateTime.Now.Subtract(dt).TotalSeconds>.1){dt=DateTime.Now;WriteOut(dt.ToString("ss.ff"),false);}}while(!quit);}staticvoidWriteOut(stringmsg,boolappendNewLine){intinCol,inRow;inCol=Console.CursorLeft;inRow=Console.CursorTop;intoutLines=getMsgRowCount(outCol,msg)+(appendNewLine?1:0);intoutBottom=outRow+outLines;如果(outBottom>outHeight)outBottom=outHeight;如果(inRowoutHeight){intscrollCount=outRow+outLines-outHeight;Console.MoveBufferArea(0,scrollCount,Console.BufferWidth,outHeight-scrollCount,0,0);outRow-=滚动计数;Console.SetCursorPosition(outCol,outRow);}控制台.SetCursorPosition(outCol,outRow);如果(appendNewLine)Console.WriteLine(msg);否则Console.Write(msg);outCol=Console.CursorLeft;outRow=Console.CursorTop;Console.SetCursorPosition(inCol,inRow);}staticintgetMsgRowCount(intstartCol,stringmsg){string[]lines=msg.Split('n');整数结果=0;foreach(stringlineinlines){结果+=(startCol+line.Length)/Console.BufferWidth;开始列=0;}返回结果+lines.Length-1;我个人会使用事件处理程序来管理一个同时处理输入和输出的控制台,创建一个类ScreenManager或其他东西,添加一个voidRunProgram()方法,创建一个带有处理程序的事件和读取输入键“Console”所需的变量.ReadKey(bool).key"staticConsolekeynewKey;在您的主程序上,创建您的类“whatevYoucallit”的实例,然后在您的主循环中为该实例的内部方法ThreadcoreThread=newThread(delegate(){myinstance.myProgramMrthod()});创建一个线程直到线程启动并运行。while(!Thread.IsAlive);然后创建主程序循环。while(true){}然后为了安全起见,加入您的自定义线程,以便主程序不会继续,直到自定义threadisclosed/disposed.customThread.Join();你现在有两个单独运行的线程。回到你的类,在你的事件处理方法中创建一个开关。switch(newkey){caseConsolekey.enterConsole.WriteLine("enterpressed");休息;等等,等等。默认值:Console.write(newkey);//将不符合上述条件的字符键写入屏幕。break;}以你想要处理键的方式坚持你所有的逻辑。HowtousemultiplemodifierkeysinC#可能会有所帮助。在您实例的方法RunProgram()或您选择调用它的任何方法中,在您完成所需的任何代码后,创建一个无限循环来检查关键更改。while(true){newKey=Console.ReadKey(true).Key;if(newKey!=oldKey){KeyChange.Invoke();这个循环存储任何被按下的键,然后检查它是否是一个新键,如果为真则触发事件。您现在拥有了您正在寻找的核心内容,一个循环请求新密钥的字符串,而主循环可以自由显示您想要的任何文本。我能想到两个可修复的错误,一个是“默认”内部开关会将大写字母或字符串打印到控制台。另一个是添加到控制台的任何文本都会添加到光标点,因此它会添加到用户刚刚输入的文本中。我会,因为我刚刚创建它,你如何管理添加到控制台的文本。我再次使用一个事件。我想,我可以使用方法和函数,但是事件会增加程序的灵活性。好的,所以我们希望能够向控制台添加文本,而不会弄乱我们键入的输入。将输入保留在底部;创建一个带有签名和字符串参数的新委托,voiddelegatemyDelegate(StringArg)。然后用这个委托创建一个事件,将其命名为换行符、新输入,随便你喜欢什么。事件处理程序将采用一个字符串参数(重新显示控制台更新文本:您想在用户输入上方插入控制台)它将采用用户输入到控制台的文本,存储它,然后将参数字符串打印到控制台,然后在下面打印用户输入。我个人是选择在方法外的顶部创建一个静态字符串,初始化为nothing,因为用的多又不想创建一个新的标识符,然后每次调用方法的时候都初始化变量,然后dispose到方法结束的时候,再重新创建一个新的就可以了。将字符串称为“输入”或其他名称。在keychange事件处理程序的默认区域添加input+=newkey。在Consolekey.enter部分控制台写入输入,然后输入=string.empty或string=""。在事件处理程序中添加一些逻辑。publicvoidOnInsert(stringArgument){Console.CursorTop-=1;//将光标移动到最左边,以便新输入覆盖旧输入。//如果arg字符串更长,则打印arg字符串,然后打印输入//string.if(Argument.Length>input.Length){Console.WriteLine(Argument);控制台.WriteLine(输入);}else{//如果用户输入的内容长于参数文本,则打印//参数文本,然后打印空格以覆盖//仍显示在屏幕上的剩余输入字符。for(inti=0;i如果您需要在用户键入时允许输出到达,我建议将输出发送到一个新窗口。这样您就可以拥有一个启动应用程序的窗口,然后它会生成一个线程来打开一个新的输入控制台,然后它继续将任何输出消息发送到原始窗口。如果你试图将所有内容都保存在同一个窗口中,我认为你会遇到太多资源锁定问题。如果你将服务器视为客户端/服务器应用程序。让服务器与发送命令和接收输出的客户端管理应用程序建立“n”个连接。客户端应用程序可以完全分离输入和输出,一个线程处理输入,一个线程处理输出。如果输入线程正在进入一行,输出线程可能会阻塞,而输出线程可能会在该行被取消或提交时阻塞。您是否尝试过调用OpenStandardInput,读取任何输入并重置其位置,然后写入输出流。然后您可以再次调用OpenStandardInput并将数据填充回流中。在我看来,没有完美的方法可以实现这一点。telnet所做的(至少我使用的最后一个版本)不打印任何输入(只是读取击键),只是在输出到达时打印输出。另一种方法是将任何需要输出到控制台的数据存储在缓冲区中,只有在用户输入命令后才打印出来。(您甚至可以为输出添加时间戳以使其更加明显。)我真的找不到更好的选择-您将不可避免地遇到使用同步I/O接口(即命令行)和后端的异步操作。以上就是C#学习教程:C#同时控制台输入输出?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
