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() を 2 回呼び出しました。2番目のものを Console.SetError() に変更した後、動作するようになりました

于 2012-05-10T22:25:38.580 に答える