Странная консоль MoveBufferArea IOException - PullRequest
1 голос
/ 08 декабря 2009

Я строил «обратную консоль» (чтобы написанные строки добавлялись вверху, а не внизу), когда я наткнулся на очень странное поведение метода 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.

Снимок экрана

Я использую Windows 7 x64 @ Corei7, 6 ГБ DDR3, так что хранение не должно быть проблемой .... Кто-нибудь знает, что может быть не так?

Ответы [ 2 ]

5 голосов
/ 08 декабря 2009

Функция API, вызывающая исключение, - ReadConsoleOutput (). На SDK doc есть соответствующий мелкий шрифт:

lpBuffer:

Указатель на буфер назначения, который получает данные, прочитанные из буфер экрана консоли. Этот указатель рассматривается как источник двумерный массив CHAR_INFO структуры, размер которых определяется параметр dwBufferSize. Общая размер массива должен быть меньше 64K .

Я выделил соответствующую фразу. Ваша программа будет бомбить, когда она попытается прокрутить более 200 строк (201 x 80 x 4 = 64320 байт, что немного странно с 65536). Возможно, это ошибка в Console.MoveBufferArea (), она не проверяет это ограничение и не пытается обойти его, что было бы легко сделать. Вы можете сообщить об ошибке на connect.microsoft.com

На данный момент вам нужно ограничить количество строк, чтобы размер буфера не превышал ограничение.

0 голосов
/ 08 декабря 2009

Консоль - это не просто другое окно. Он действительно предназначен для двунаправленного ввода, перенаправления на уровне оболочки и т. Д. И может иметь некоторые странные проблемы при попытке сделать что-то подобное. В основном это связано с тем, что вы работаете с буфером файловых потоков, а не просто с текстом на экране.

Рассматривали ли вы просто создание окна для размещения вашей "консольной" информации, поскольку вы явно делаете нестандартный поток вывода? Вы можете просто перенаправить ваш консольный ввод-вывод в свой собственный поток ( здесь приведен пример этого в VB.NET ) и отобразить это в окне самостоятельно, используя что-то вроде RichTextBox.

Если вы используете «обращенную» консоль, вы, очевидно, не используете средства перенаправления командной строки или механизмы ввода - в этом случае пользовательское окно, вероятно, является более подходящим подходом.

...