Search code examples
c#loggingsynchronizationlogfiles

Static Logger in separate thread?


I've made my Logger, that logs a string, a static class with a static so I can call it from my entire project without having to make an instance of it. quite nice, but I want to make it run in a separate thread, since accessing the file costs time

is that possible somehow and what's the best way to do it?

Its a bit of a short description, but I hope the idea is clear. if not, please let me know.

Thanks in advance!

By the way any other improvements on my code are welcome as well, I have the feeling not everything is as efficient as it can be:

internal static class MainLogger
    {
        internal static void LogStringToFile(string logText)
        {
            DateTime timestamp = DateTime.Now;
            string str = timestamp.ToString("dd-MM-yy  HH:mm:ss ", CultureInfo.InvariantCulture) + "\t" + logText + "\n";
            const string filename = Constants.LOG_FILENAME;
            FileInfo fileInfo = new FileInfo(filename);
            if (fileInfo.Exists)
            {
                if (fileInfo.Length > Constants.LOG_FILESIZE)
                {
                    File.Create(filename).Dispose();
                }
            }
            else
            {
                File.Create(filename).Dispose();
            }
            int i = 0;
            while(true)
            {
                try
                {
                    using (StreamWriter writer = File.AppendText(filename))
                    {
                        writer.WriteLine(str);
                    }
                    break;
                }
                catch (IOException)
                {
                    Thread.Sleep(10);
                    i++;
                    if (i >= 8)
                    {
                        throw new IOException("Log file \"" + Constants.LOG_FILENAME + "\" not accessible after 5 tries");
                    }
                }
            }
        }
    }
enter code here

Solution

  • If you're doing this as an exercise (just using a ready made logger isn't an option) you could try a producer / consumer system.

    1. Either make an Init function for your logger, or use the static constructor - inside it, launch a new System.Threading.Thread, which just runs through a while(true) loop.
    2. Create a new Queue<string> and have your logging function enqueue onto it.
    3. Your while(true) loop looks for items on the queue, dequeues them, and logs them.
    4. Make sure you lock your queue before doing anything with it on either thread.