14

基本的にコンソールアプリケーションであるマルチスレッドアプリケーション(サーバー)に取り組んでいます。デフォルトでは白色であるコンソールに処理ログを表示します。ただし、トランザクションが成功した場合はテキストを緑色で表示し、トランザクションが失敗した場合はテキストを赤色で表示します。そのため、このために Program.cs に 3 つの個別の関数があります。

簡易ログの場合

public static void Write(string text)
{
        try
        {
            Console.Out.Write(text);
        }
        catch (Exception)
        { }
    }

トランザクションが失敗した場合、色を赤に変更し、印刷してから白に戻します

    public static void WriteError(string text)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("\t" + text);
        Console.ForegroundColor = ConsoleColor.White;
    }

トランザクションを成功させるために、色を緑に変更し、印刷してから白に戻します

    public static void WriteSuccess(string text)
    {
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("\t" + text);
        Console.ForegroundColor = ConsoleColor.White;

    }

問題は、200 を超えるクライアントが接続し、各クライアントのトランザクションのログがコンソールに出力される場合です。また、単一行の緑のような色を変更すると、通常のログの他の多くの行も緑になります。では、この問題を解決するにはどうすればよいか教えてください。

4

4 に答える 4

21

クラスがコンソールに書き込みを行っている唯一のクラスである場合、他の人が述べたように、単一のプライベート オブジェクトのロックが機能します。

ただし、他のライターがいる場合は、それらと同期する必要があります。そうしないと、ロック内にいる間に書き込みが行われる可能性があります。の実装を見ると、それ自体が ( を使用して) 同期するであるConsoleことがわかります。これは、それを同期オブジェクトとして使用すると、他のライターと同期されることを意味します。Console.OutSyncTextWriter[MethodImplAttribute(MethodImplOptions.Synchronized)]

lock (Console.Out)
{
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine("\t" + text);
    Console.ForegroundColor = ConsoleColor.White;
}

他のライターも色を設定し、独自の同期オブジェクトを使用している場合、これはまだ正しく機能しません。ただし、他のライターも同期している場合は機能しConsole.Outます。

このアプローチの問題点は、実装の詳細に依存していることですが、私はこれ以上の解決策を知りません。

于 2015-08-14T14:01:09.870 に答える
1

ロックステートメントを使用して、色付きの書き込みをアトミックにします。

// Only one thread can enter this section at a time
lock(_lockObj) 
{
   Console.ForegroundColor = ConsoleColor.Green;
   Console.WriteLine("\t" + text);
   Console.ForegroundColor = ConsoleColor.White;
}

_lockObjは、クラスのプライベート静的メンバーとして宣言する必要があります。

private static Object _lockObj = new Object();
于 2012-12-13T14:07:39.977 に答える
0

Mutex またはモニターを使用して、コンソールへのアクセスを同期する必要があります (lockオブジェクトによっては簡単です)。

于 2012-12-13T14:06:02.767 に答える