2009-12-08 72 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的東西將它自己顯示在窗口中。

如果你正在做一個「反向」控制檯,顯然你不使用命令行重定向工具或輸入機制 - 在這種情況下,自定義窗口可能是一個更好的方法。