Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET 2.0 : File.AppendAllText(...) - Thread safe implementation

As an exercise in idle curiosity more than anything else, consider the following simple logging class:

internal static class Logging
{
    private static object threadlock;

    static Logging()
    {
        threadlock = new object(); 
    }

    internal static void WriteLog(string message)
    {
        try
        {
            lock (threadlock)
            {
                File.AppendAllText(@"C:\logfile.log", message);
            }
        }
        catch
        {
            ...handle logging errors...
        }
    }
}

Is the lock needed around File.AppendAllText(...) or is the method inherently thread-safe by its own implementation ?

Searching for information on this yields a lot of contradictory information, some say yes, some say no. MSDN says nothing.

like image 476
MrEyes Avatar asked Jan 26 '11 20:01

MrEyes


People also ask

Is AppendAllText thread safe?

It is thread safe in the sense that it opens the file with Read sharing, so assuming your filesystem honors file locks, only one thread will be allowed to write to the file at a time.

Is appending to a file thread safe?

Appending a file from multiple threads is not thread-safe and will result in overwritten data and file corruption.

What is a lock free solution to making writing to a file thread safe?

A thread safe, efficient, lock free approach would be to use memory mapping, which works as follows: create the result file of (at least) the total length needed. open() the file for read/write. mmap() it to some place in memory.

What is AppendAllText C#?

AppendAllText(String, String, Encoding) Appends the specified string to the file using the specified encoding, creating the file if it does not already exist. public: static void AppendAllText(System::String ^ path, System::String ^ contents, System::Text::Encoding ^ encoding); C# Copy.


1 Answers

File.AppendAllText is going to acquire an exclusive write-lock on the log file, which would cause any concurrent thread attempting to access the file to throw an exception. So yes, you need a static lock object to prevent multiple threads from trying to write to the log file at the same time and raising an IOException.

If this is going to be an issue, I'd really suggest logging to a database table which will do a better job of handling concurrent log writers.

Alternatively, you can use TextWriterTraceListener which is thread-safe (well, it's going to do the locking for you; I'd rather write as little of my own multithreaded code as possible).

like image 55
jason Avatar answered Sep 19 '22 05:09

jason