English 中文(简体)
Caching System.Console output
原标题:

We have some methods that output a lot of coloured text to the Console.

It s actually a menu that is built by looping through a collection of data.

Because we are writing item by item (and one line contains many items in different colours), this process is rather slow on low-end and mid-end machines. On those machines you can see each line being written one by one and it s rather frustrating for the end user.

This menu has to be displayed many times so I m wondering if I can t just "cache" this output somehow. If there was no coloured text I d simply store the output in a string and write it in one go, but I don t want to lose colour information.

Any suggestions?

Update: Just to give an idea of how intensive the output is: Update 2: Updated the sloppy code, but still want to buffer the output somehow. MoveBufferArea proves to be a partial solution (it creates unwanted scrollbars)

DefaultBanner();

WriteLine("Available tests:
", ConsoleColor.White);

var methodNames = methods.Select(m => ((TestAttribute)m.GetCustomAttributes(false)[0]).Name).ToArray();

int vertical = 0;
for (int i = 1; i <= methods.Length; i++)
{
    if (i > methods.Length / 2)
    {
        Console.SetCursorPosition(40, 4 + vertical++);
    }

    Write("(");
    Write(i, ConsoleColor.Yellow);
    WriteLine(") {0:00}", methodNames[i - 1]);
}

Write("
(");
Write(items.Count + 1, ConsoleColor.Yellow);
Write(") Set address | (");
Write(items.Count + 2, ConsoleColor.Yellow);
Write(") View Log | (");
Write(items.Count + 3, ConsoleColor.Yellow);
Write(") Open Log directory 
(");
Write(items.Count + 4, ConsoleColor.Yellow);
Write(") Open configuration | (");
Write(items.Count + 5, ConsoleColor.Yellow);
Write(") View current configuration | (");
Write(items.Count + 6, ConsoleColor.Yellow);
WriteLine(") Quit");
Write("
Your selection: ");

int command = 0;
while (!ConsoleReader<int>.TryReadValueInRange(1, items.Count + 6,out command));
return command;

The Write methods are simply helper methods that encapsulate some behaviour of the System.Console class so we wouldn t have to keep setting the colour.

问题回答

Maybe you could something clever using the MoveBufferArea function. What about if you had a area of the buffer that was not currently visible to the user. You could create your buffermenu there and then copy the whole region to a part of the visible buffer in one go. I don t know how much control you have over the visible/non-visible areas of the buffer and if you can use them like this, it s just a suggestion.

The only other option I can think of is creating your own control that mimics the console. You could then make allow buffered reads/writes or only refresh after you ve made several changes. But this could be a lot of extra work.

Is there a way to move your attribute-evaluating logic "outside the loop?" I suspect it s not the quickest part of your code.

I don t know if it is possible for your project, but one option is using some type of markup language to store the color inside the string itself, for example <yellow>Text in yellow</yellow> (or your could use plain CSS selectors, or whatever). This way you could use a plain string cache.

By the way remember that the .NET Framework already implements one such cache: see String.Intern and String.IsInterned.

Keep in mind that Console is a configurable device, meaning that you can write your own (though I don t recommend it). There is a way to specify in config file which class does Tracing and which class does Debug output.

Is there a way to ask your clients to make sure they are running hardware-accelerated graphics (check the drivers)? If they are running with VGA-Only default Microsoft driver, then console will be painfully slow.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签