C#控制台:在读取时写入并保留结构

时间:2009-05-23 17:16:25

标签: c# multithreading console client-server

我正在编写一个通过TCP连接到服务器的C#控制台应用程序,它使用一个单独的线程来侦听来自服务器的传入消息,我希望它将它们写入控制台,同时从中读取消息控制台。我能够做到这一点,但我有一个问题。

当我输入并收到消息时,控制台显示此内容:

  

来自服务器的消息
  来自服务器的消息
  我的msmsg来自服务器
  g到服务器

我希望它将我的消息与服务器消息分开,如下所示:

  

来自服务器的消息
  来自服务器的消息
  来自服务器的消息
  我的服务器消息

如果我收到一条消息,我仍然希望保留我输入的消息,但我不希望它与收到的消息混淆,我希望它在最后一行保持完整。

我能这样做吗?怎么样?

当来自服务器的消息进来时,我可以将消息转移到控制台的末尾吗?

4 个答案:

答案 0 :(得分:1)

您无法通过C#中的BCL直接执行此操作。但是,有两种主要的替代方案。

1)将其转换为GUI应用程序,并具有单独的输入/输出区域。这是用户POV中最“清晰”的选项,但需要GUI应用程序而不是控制台应用程序。

2)P /直接调用console API。这使您可以逐点完全控制控制台的视图。请参阅SetConsoleCursorPosition和WriteConsole等。

答案 1 :(得分:1)

您需要在某些lock上使用object来同时使用控制台停止两个线程。声明如下:

public static class ThreadSafeConsole
{
    private static object _lockObject = new object();

    public static void WriteLine(string str)
    {
        lock (_lockObject) 
        {
            Console.WriteLine(str);
        }
    }
}

现在拨打ThreadSafeConsole.WriteLine而不是Console.WriteLine

答案 2 :(得分:1)

我相信这实际上可以使用标准的.NET控制台API,使用一些hackery。您需要做的是创建一个异步的Read / ReadLine方法(我假设您已经完成了,根据您的帖子判断)并允许在新数据到达时立即取消它。我假设你现在正在逐行发送输入。 “新数据处理程序”的伪代码可能是这样的:

Save the current input buffer.
Cancel the current asynchronous read.
Reset the cursor position to the end of the last writing of new data.
Output the new data.
Save the cursor position.
Restart the asynchronous read event.

特别是,您需要使用Console.CursorLeftConsole.CursorTop属性。您可以通过直接与Win32 API控制台功能接口来避免 hackery的某些,但它可能不值得打扰。

希望有所帮助。

答案 3 :(得分:0)

如果我理解正确,你必须为你的应用程序定义'打字到控制台'的开头和结尾是什么,这样你就可以在发生这种情况时锁定一个对象,而不是从你的插件中插入消息监听器线程到您输入的文本。

public static Object consoleLock = new Object();
public static void Main(string[] args)
{
    lock (consoleLock)
    {
        // now nothing can write to the console (if it's trying to lock onto it)
        Console.WriteLine("Please Input Something");
        // read from console
    }
    // now, your separate thread CAN write to the console - without 
    // interrupting your input process
}