2009-12-08 75 views
1

我是建设一个“反向控制台”(这样写的线将自己附加在上面的,而不是底部),我偶然发现了Console.MoveBufferArea方法的一个非常奇怪的现象:奇怪控制台MoveBufferArea IOException异常

static void Main() 
    { 
     for (var _linesWritten = 0; _linesWritten < 1000; _linesWritten++) 
     { 
      var _height = Math.Min(Console.BufferHeight-1, _linesWritten); 
      Console.MoveBufferArea(0, 0, Console.BufferWidth, _height, 0, 1); 
      Console.SetCursorPosition(0, 0); 
      Console.WriteLine("Line {0} aaaaaaaaaa", _linesWritten); 
      Console.ResetColor(); 
     } 
    } 

当我将其称为固定次数时,它会引发System.IO.IOException异常:“没有足够的存储空间来处理此命令”。我发现这取决于正在移动的缓冲区的数量。在更改Console.BufferWidth属性时,引发异常之前写入的行数会发生变化。

Screenshot

我运行Windows 7 X64的@ Corei7,6GB DDR3,所以存储shuldn​​'t是问题.... 没有任何人有什么线索可能是错的?

回答

5

导致异常的API函数是ReadConsoleOutput()。该SDK文档具有一些相关的小字:

lpBuffer:

的指针,该 接收从 控制台屏幕缓冲器读出的数据的目标缓冲区。该指针为 ,其视为 二维数组CHAR_INFO 结构的起点,其大小由 dwBufferSize参数指定。该阵列的总大小 必须是小于 64K

我粗体显示了相关的短语。当你的程序试图滚动超过200行时(201 x 80 x 4 = 64320字节,从65536中稍微离开一点),你的程序就会弹出。这可能是Console.MoveBufferArea()中的一个错误,它不检查此限制,也不尝试解决此问题,这很容易实现。您可以在connect.microsoft.com上报告错误

现在,您必须限制行数,以便缓冲区大小不超过限制。

0

控制台不只是另一个窗口。它的目的是允许双向输入,shell级别重定向等,当你尝试这样做时可能会遇到一些奇怪的问题。这主要是由于您正在处理文件流缓冲区,而不仅仅是屏幕上的文本。

你是否认为只是制作一个窗口来托管你的“控制台”信息,因为你显然是在做一个非标准的输出流?您可以将控制台I/O重定向到您自己的流(here is a sample of doing this in VB.NET),并使用类似RichTextBox的东西将它自己显示在窗口中。

如果你正在做一个“反向”控制台,显然你不使用命令行重定向工具或输入机制 - 在这种情况下,自定义窗口可能是一个更好的方法。