开发者

Is there a way to continuously mirror the result of Console.Write to a collection (array,list,etc)?

开发者 https://www.devze.com 2023-02-18 09:19 出处:网络
I have a console program, I\'d like to continuously mirror the result of Console.Write to a collection, which I can look at the tail of in real time. The collection could be an array, a list, etc.

I have a console program, I'd like to continuously mirror the result of Console.Write to a collection, which I can look at the tail of in real time. The collection could be an array, a list, etc.

I assume I'd have to use some sort of event handler?

I don't mind being pointed in the direction of a 3rd party library, e.g. NLog.

Update

I need to maintain a collection in memory, which mirrors the current console state (I can then send to a remote WinForms app using sockets). Details aside, I think I can do this with a 开发者_如何学运维few lines of C# - I don't want to add a huge logging library without a good need for it.


The Console class allows you to replace the output and error streams. Just what you need here, you can replace them with a TextWriter that also logs what is written. A sample implementation:

    class ConsoleLogger : System.IO.TextWriter {
        private System.IO.TextWriter oldOut;
        private Queue<string> log = new Queue<string>();
        private StringBuilder line = new StringBuilder();
        private object locker = new object();
        private int newline;
        private int logmax;

        public ConsoleLogger(int history) {
            logmax = history;
            oldOut = Console.Out;
            Console.SetOut(this);
        }
        public override Encoding Encoding {
            get { return oldOut.Encoding; }
        }
        public override void Write(char value) {
            oldOut.Write(value);
            lock (locker) {
                if (value == '\r') newline++;
                else if (value == '\n') {
                    log.Enqueue(line.ToString());
                    if (log.Count > logmax) log.Dequeue();
                    line.Length = newline = 0;
                }
                else {
                    for (; newline > 0; newline--) line.Append('\r');
                    line.Append(value);
                }
            }
        }
    }

Usage:

    static void Main(string[] args) {
        var outLogger = new ConsoleLogger(100);
        // etc...
    }


You could probably write a new TextWriter who's Write calls populate a list instead of writing to a stream. You would then need to set this through Console.SetOut(...)


Using Console.SetOut you can set your custom implemented TextWriter.


You can create a simple helper method and call that instead of Console.Write.

private void WriteToConsole(string message)
{
    myList.Add(message);

    Console.Write(message);
}


If you want to write code like:

    WriteToConsole("{0} tel is: {1:+### ### ### ###}", "Name", 242352356578);

Then you could have code:

    private static Queue<String> q = new Queue<String>(1000);
    private static void WriteToConsole(String message)
    {
        q.Enqueue(message);
        Console.Write(message);
    }
    private static void WriteToConsole(String message, params Object[] r)
    {
        String s = String.Format(message, r);
        q.Enqueue(s);
        Console.Write(s);
    }


Use log4net for continuosly dump in the file, and then use this for tail: http://tailf.codeplex.com/


See Capturing console output from a .NET application (C#).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号