9

我正在编写一个包含自定义记录器的控制台应用程序。记录器需要将发送到 Console.Error 的任何内容涂成红色。我现在有第三方引用,它们也写入 Console.Out 和 Console.Error,所以我必须以一种考虑到它们的方式来执行此操作,因为我没有它们的源代码。我已经设置了我的记录器,因此任何写入控制台的代码都将通过调用 Console.SetOut 和 Console.SetError 方法来使用我的记录器的 TextWriter。它有点工作,但我猜有某种同步问题?在我的 ErrorWriter 类中,您可以看到我正在设置控制台的前景色,然后调用 base.Write() 但结果与预期不符。来自 Console.Out 的应为灰色的文本变为红色,而在中途突然变为灰色。它一直在同一字符位置从红色变回灰色,但我假设 base.Write() 实际上并没有立即吐出到控制台;有某种滞后时间/缓冲区。我试过调用 base.Flush() 但这会使 Console.Out 中的所有文本都变成红色,这更糟。我该如何解决这个问题?

public class Logger
{
    private static TextWriter _out;
    private static ErrorWriter _error;

    public Logger()
    {
        Initiliaze();
    }

    public static TextWriter Out
    {
        get
        {
            return _out;
        }
    }

    public static TextWriter Error
    {
        get
        {
            return _error;
        }
    }

    private static void Initiliaze()
    {
        if (_out == null)
            _out = new StreamWriter(Console.OpenStandardOutput());
        if (_error == null)
            _error = new ErrorWriter(Console.OpenStandardError());

        Console.SetOut(Out);
        Console.SetOut(Error);
    }
}

public class ErrorWriter : StreamWriter
{
    // constructors omitted to save space

    public override void Write(string value)
    {
            Console.ForegroundColor = ConsoleColor.Red;
            base.Write(value);
            //base.Flush();
            Console.ResetColor();
    }

    public override Encoding Encoding
    {
        get { return Encoding.Default; }
    }
}
4

2 回答 2

7

您可以装饰该方法以执行此操作:

public class ConsoleErrorWriterDecorator : TextWriter
{
    private TextWriter m_OriginalConsoleStream;

    public ConsoleErrorWriterDecorator(TextWriter consoleTextWriter)
    {
        m_OriginalConsoleStream = consoleTextWriter;
    }

    public override void WriteLine(string value)
    {
        ConsoleColor originalColor = Console.ForegroundColor;
        Console.ForegroundColor = ConsoleColor.Red;

        m_OriginalConsoleStream.WriteLine(value);

        Console.ForegroundColor = originalColor;
    }

    public override Encoding Encoding
    {
        get { return Encoding.Default; }
    }

    public static void SetToConsole()
    {
        Console.SetError(new ConsoleErrorWriterDecorator(Console.Error));
    }
}

不要忘记运行“ConsoleErrorWriterDecorator.SetToConsole();” 在你开始写控制台之前

于 2012-05-10T12:16:42.670 回答
2

原来是一个愚蠢的复制/粘贴错误!我有两次调用 Console.SetOut()。现在它在将第二个更改为 Console.SetError() 后工作

于 2012-05-10T22:25:38.580 回答