奇怪的控制台MoveBufferArea IOException

时间:2009-12-08 01:23:47

标签: c# console ioexception

我正在构建一个“反向控制台”(这样写入的行会自己附加在顶部而不是底部)因为我偶然发现了Console.MoveBufferArea方法的一个非常奇怪的行为:

    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,所以存储不是问题.... 有没有人知道可能出现什么问题?

2 个答案:

答案 0 :(得分:5)

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

  

lpBuffer:
  
  指向目标缓冲区的指针   接收从中读取的数据   控制台屏幕缓冲区这个指针是   被视为一个人的起源   CHAR_INFO的二维数组   大小由...指定的结构   dwBufferSize参数。总数   数组的大小必须小于   64K

我加粗了相关的短语。当你的程序试图滚动超过200行(201 x 80 x 4 = 64320字节,奇怪地从65536一点点偏离)时,你的程序会爆炸。它可以说是Console.MoveBufferArea()中的一个错误,它不会检查这个限制,也不会尝试解决它很容易做到的问题。您可以在connect.microsoft.com上报告错误

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

答案 1 :(得分:0)

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

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

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