奇怪的控制台 MoveBufferArea 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 属性时,抛出异常之前写入的行数会发生变化。
我运行的是 Windows 7 x64 @ Corei7,6gb DDR3 ,所以存储不应该是问题...... 有人知道可能出了什么问题吗?
I was building a "reverse console" (so that the written lines would append themselves on the top instead of the bottom) as I stumbled upon a very strange behavior of the Console.MoveBufferArea method:
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();
}
}
When i call it a fixed number of times it throws an System.IO.IOException saying: "Not enough storage is available to process this command". I figured out that it depends on the amount of the buffer area being moved around. The number of lines written before the exception is thrown changes as I change the Console.BufferWidth property.
I am running Windows 7 x64 @ Corei7, 6gb DDR3, so storage shuldn't be the problem....
Does anybody have a clue what could be wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
导致异常的API函数是ReadConsoleOutput()。 SDK 文档有一些相关的小字:
我将相关短语加粗。当你的程序尝试滚动超过 200 行(201 x 80 x 4 = 64320 字节,奇怪的是,与 65536 相比有点偏离)时,它就会崩溃。这可以说是 Console.MoveBufferArea() 中的一个错误,它不会检查此限制,也不会尝试解决它,这很容易做到。您可以在 connect.microsoft.com 上报告该错误。
目前,您必须限制行数,以便缓冲区大小不超过限制。
The API function that causes the exception is ReadConsoleOutput(). The SDK doc has some relevant small print:
I bolded the relevant phrase. Your program will bomb when it tries to scroll more than 200 lines (201 x 80 x 4 = 64320 bytes, oddly off a bit from 65536). It is arguably a bug in the Console.MoveBufferArea(), it doesn't check for this limitation nor tries to work around it which would be easy to do. You can report the bug at connect.microsoft.com
For now, you'll have to limit the number of lines so the buffer size doesn't exceed the limit.
控制台不仅仅是另一个窗口。它的真正目的是允许双向输入、shell 级重定向等,并且当您尝试执行此类操作时可能会出现一些奇怪的问题。这主要是因为您正在使用文件流缓冲区,而不仅仅是屏幕上的文本。
您是否考虑过制作一个窗口来托管您的“控制台”信息,因为您显然正在执行非标准输出流?您可以将控制台 I/O 重定向到您自己的流(这里是在 VB.NET 中执行此操作的示例),并使用 RichTextBox 等工具将其显示在自己的窗口中。
如果您正在使用“反向”控制台,则显然您没有使用命令行重定向工具或输入机制 - 在这种情况下,自定义窗口可能是更好的方法。
The Console is not just another Window. It's really intended to allow bi-directional input, shell level redirection, etc, and can have some odd issues when you try to do things like this. This is mainly due to the fact that you're working with file stream buffers, not just text on a screen.
Have you considered just making a Window to host your "console" information, since you're obviously doing a non-standard output stream? You could just redirect your Console I/O to your own stream (here is a sample of doing this in VB.NET), and display this in a window yourself, using something like a RichTextBox.
If you're doing a "reversed" console, you're obviously not using the command line redirection facilities, or input mechanisms - in which case a custom window is probably a nicer approach.