How do I lock the console across threads in C#.NET

2019-02-06 18:13发布

I have a logger class that handles various information display with pretty colors (yay.). However, since it writes to the console in separated steps (i.e. set color to red, write text, set color to gray, write text, for something that would render "[Error] Description..." with the error being in red), but I have a multithreaded application, so the steps can get mixed up and print random stuff in random colors.

I am aware of the lock keyword, however it will not work with a static class such as the console.

Here is some example code if I was unclear:

using System;
using System.Text;

    namespace N.Utilities.IO
    {
        public static class Logger
        {
            private static void WriteColored(string value, ConsoleColor color)
            {
                if (Logger.UseColor)
                {
                    Console.ForegroundColor = color;
                    Console.Write(value);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                else
                {
                    Console.Write(value);
                }
            }   

            private static void WriteLineColored(string value, ConsoleColor color)
            {
                if (Logger.UseColor)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(value);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                else
                {
                    Console.Write(value);
                }
            }

            private static bool useColor = true;

            public static bool UseColor
            {
                get
                {
                    return Logger.useColor;
                }
                set
                {
                    Logger.useColor = value;
                }
            }

            public static void Inform(string value)
            {
                Logger.WriteColored("    [Info] ", ConsoleColor.White);
                Console.WriteLine(value);
            }

            public static void Warn(string value)
            {
                Logger.WriteColored(" [Warning] ", ConsoleColor.Yellow);
                Console.WriteLine(value);
            }

            public static void Error(string value)
            {
                Logger.WriteColored("   [Error] ", ConsoleColor.Red);
                Console.WriteLine(value);
            }
    }

1条回答
Viruses.
2楼-- · 2019-02-06 18:36

Your class needs:

private static readonly object ConsoleWriterLock = new object();

Then you can lock on this before writing to the console.

lock(ConsoleWriterLock)
{
     //Your code here
}

The lock keyword will work with a static class, you just need to provide a static readonly object to lock on.

查看更多
登录 后发表回答